2016-03-14 4 views
4

Я пытаюсь использовать NEST для возврата различных объектов, полученных из общего подкласса.Возвращение нескольких экземпляров производного класса из Elasticsearch с использованием NEST и .NET

В этом примере у меня есть базовый класс под названием «Человек», а затем я получил классы, называемые «Пожарный» и «Учитель». Экземпляры хранятся в индексе под названием «люди».

Я хотел бы сделать поиск по моему индексу и вернуть смесь Пожарных и Учителей, но лучшее, что я могу вернуть, это список людей.

The documentation призывает использовать 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" 
      } 
     }] 
    } 
} 

Как получить НЕСТ, чтобы вернуть смешанный список экземпляров, полученных из базового класса?

Большое спасибо!

-Z

+0

какой версия НЕСТА и какую версия Elasticsearch вы используете? –

+0

@ russ-cam, все было установлено из NuGet, который, кажется, версии 2.0.4. (как для Elasticsearch.net, так и для NEST) – zorlack

+0

какая версия Elasticsearch вы используете? –

ответ

3

NEST supports Covariant results и в NEST 2.х, именование метода на ISearchResponse<T> было изменено на .Type() для выравнивания с параметром маршрута, который он представляет в URI при создании запроса на Elasticsearch (.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

Не беспокойтесь, рад помочь :) –