2016-03-14 104 views
4

我想使用NEST来返回从公共子类派生的各种对象。使用NEST和.NET从Elasticsearch返回多个派生类实例

在这个例子中,我有一个名为“Person”的基类,然后我派生了一个名为“Firefighter”和“Teacher”的类。实例存储在名为“people”的索引中。

我想对我的索引进行搜索并返回消防队员和教师组合,但我可以找到的最好的人员名单。

​​3210要求使用ISearchResponse.Types,但我没有看到该函数存在。 This post,这里StackOverflow,也引用.Types函数,但我只是没有看到它作为一个选项。

这是我试图解决的问题的一个例子。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using Nest; 
using Elasticsearch; 
using Elasticsearch.Net; 

namespace ElasticSearchTest 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var myTeacher = new Teacher { id="1", firstName = "Steve", lastName = "TheTeacher", gradeNumber = 8 }; 
      var myFiregighter = new Firefighter { id="2", firstName = "Frank", lastName = "TheFirefighter", helmetSize = 12 }; 

      SingleNodeConnectionPool esPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
      ConnectionSettings esSettings = new ConnectionSettings(esPool); 
      esSettings.DefaultIndex("people"); 
      Nest.ElasticClient esClient = new ElasticClient(esSettings); 

      esClient.DeleteIndex("people"); 
      esClient.Index<Teacher>(myTeacher); 
      esClient.Index<Firefighter>(myFiregighter); 

      System.Threading.Thread.Sleep(2000); 

      ISearchResponse<Person> response = esClient.Search<Person>(s => s 
       .AllTypes() 
       .MatchAll() 
       ); 

      foreach (Person person in response.Documents) 
       Console.WriteLine(person); 
     } 

     public class Person 
     { 
      public string id { get; set; } 
      public string firstName { get; set; } 
      public string lastName { get; set; } 
      public override string ToString() { return String.Format("{0}, {1}", lastName, firstName);} 
     } 
     public class Firefighter : Person 
     { 
      public int helmetSize { get; set; } 
     } 
     public class Teacher : Person { 
      public int gradeNumber { get; set; } 
     } 
    } 
} 

的数据似乎里面Elasticsearch结构正确:

{ 
    took: 1, 
    timed_out: false, 
    _shards: { 
     total: 5, 
     successful: 5, 
     failed: 0 
    }, 
    hits: { 
     total: 2, 
     max_score: 1, 
     hits: [{ 
      _index: "people", 
      _type: "firefighter", 
      _id: "2", 
      _score: 1, 
      _source: { 
       helmetSize: 12, 
       id: "2", 
       firstName: "Frank", 
       lastName: "TheFirefighter" 
      } 
     }, { 
      _index: "people", 
      _type: "teacher", 
      _id: "1", 
      _score: 1, 
      _source: { 
       gradeNumber: 8, 
       id: "1", 
       firstName: "Steve", 
       lastName: "TheTeacher" 
      } 
     }] 
    } 
} 

我怎么NEST返回从基类派生实例的混合列表?

非常感谢!

-Z

+0

什么版本Elasticsearch您使用的是什么版本的巢和? –

+0

@ russ-cam,一切都是从NuGet安装的,它似乎是2.0.4版本。 (对于Elasticsearch.net和NEST) – zorlack

+0

您使用的是哪种版本的Elasticsearch? –

回答

3
NEST supports Covariant results

和NEST 2.x中,上ISearchResponse<T>该方法的命名改变为.Type()与它发出请求到Elasticsearch时表示在URI路线参数对齐(.Type()可以是一种或多种类型)。

协变结果NEST 2.X的一个例子是

static void Main(string[] args) 
{ 
    var myTeacher = new Teacher { id = "1", firstName = "Steve", lastName = "TheTeacher", gradeNumber = 8 }; 
    var myFiregighter = new Firefighter { id = "2", firstName = "Frank", lastName = "TheFirefighter", helmetSize = 12 }; 

    SingleNodeConnectionPool esPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200")); 
    ConnectionSettings esSettings = new ConnectionSettings(esPool); 
    esSettings.DefaultIndex("people"); 
    Nest.ElasticClient esClient = new ElasticClient(esSettings); 

    if (esClient.IndexExists("people").Exists) 
    { 
     esClient.DeleteIndex("people"); 
    } 

    esClient.Index<Teacher>(myTeacher, i => i.Refresh()); 
    esClient.Index<Firefighter>(myFiregighter, i => i.Refresh()); 

    // perform the search using the base type i.e. Person 
    ISearchResponse<Person> response = esClient.Search<Person>(s => s 
     // Use .Type to specify the derived types that we expect to return 
     .Type(Types.Type(typeof(Teacher), typeof(Firefighter))) 
     .MatchAll() 
    ); 

    foreach (Person person in response.Documents) 
     Console.WriteLine(person); 
} 

public class Person 
{ 
    public string id { get; set; } 
    public string firstName { get; set; } 
    public string lastName { get; set; } 
    public override string ToString() { return String.Format("{0}, {1}", lastName, firstName); } 
} 
public class Firefighter : Person 
{ 
    public int helmetSize { get; set; } 
} 
public class Teacher : Person 
{ 
    public int gradeNumber { get; set; } 
} 
+0

非常有帮助的拉斯。非常感谢! – zorlack

+0

不用担心,乐意帮忙:) –