c# – 使用NEST和.NET从Elasticsearch返回多个派生类实例

我正在尝试使用NEST返回从公共子类派生的各种对象.

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

我想搜索我的索引并返回一群消防员和教师,但我能找到的最好的是一个人员列表.

The documentation要求使用ISearchResponse.Types,但我没有看到此函数存在. This post,这里在*上,也引用了.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

解决方法:

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; }
}
上一篇:将ElasticSearch服务器上的映射与来自C#类的推断映射进行比较?


下一篇:c# – Elasticsearch NEST:不带通配符的部分/全文搜索