搜索多个索引并返回正确的类型

时间:2019-07-04 15:25:22

标签: c# .net elasticsearch nest

我在Elasticsearch中设置了两个索引,用于存储不同类型的数据,并且我尝试同时使用两个索引中的nest获取搜索结果。我已经建立了如下模型...

public class Person
{
    [Number(Name="person_id")]
    public int Id { get; set; }
    [Date(Name = "person_created")]
    public DateTime Created { get; set; }
    ...
}

public class Work {
    [Number(Name="work_id")]
    public int Id { get; set; }
    [Date(Name = "work_created")]
    public DateTime Created { get; set; }
    ...
}

查询单个索引时,我可以执行以下操作并将结果重新映射到我的模型类型...

var request = new SearchRequest("works")
{
    From = searchQuery.Offset,
    Size = searchQuery.PageSize,
    Query = new QueryStringQuery { Query = searchQuery.SearchTerm },
 };

 var result = _elasticClient.Search<Work>(request);

但是,当执行如下查询时,如何告诉nest将每个索引的结果映射到哪种类型?

var request = new SearchRequest("works,person")
{
     ...
}
var result = _elasticClient.Search<object> ...

我看到的其他答案建议做类似以下的事情,但我认为NEST 7.0中的Types函数已被删除...

client.Search<object>(s => s
    .Size(100)
    .SearchType(SearchType.Count)
    .Type(Types.Type(typeof(Dog), typeof(Cat)))

1 个答案:

答案 0 :(得分:1)

如果您可以控制文档索引编制,则可以通过将.NET类型放置在Elasticsearch索引中的文档中来利用NEST中的possibility to customize JSON serialization流程。这样,NEST会将文档反序列化为正确的类型。

class Program
{
    public class Person  
    {
        [Number(Name="person_id")]
        public int Id { get; set; }
        [Date(Name = "person_created")]
        public DateTime Created { get; set; }
    }

    public class Work 
    {
        [Number(Name="work_id")]
        public int Id { get; set; }
        [Date(Name = "work_created")]
        public DateTime Created { get; set; }
    }

    static void Main(string[] args)
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var connectionSettings =
            new ConnectionSettings(pool,
                sourceSerializer: (builtin, settings) => new JsonNetSerializer(builtin, settings,
                    () => new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.All}
                ));
        var client = new ElasticClient(connectionSettings);

        var deleteIndexResponse = client.Indices.Delete("person,work");

        var createIndexResponse = client.Indices
            .Create("person", i => i.Map<Person>(m => m.AutoMap()));
        var createIndexResponse2 = client.Indices
            .Create("work", i => i.Map<Work>(m => m.AutoMap()));

        client.Index(new Person {Id = 1, Created = DateTime.UtcNow},
            i => i.Index("person"));
        client.Index(new Work {Id = 1, Created = DateTime.UtcNow},
            i => i.Index("work"));

        client.Indices.Refresh();

        var searchResponse = client.Search<object>(s => s
            .Index("person,work")
            .Query(q => q.MatchAll()));

        foreach (var document in searchResponse.Documents)
        {
            Console.WriteLine($"Person? {document is Person} Work? {document is Work}");
        }
    }
}

打印:

Person? True Work? False
Person? False Work? True

NEST.JsonNetSerializer软件包需要安装在您的项目中。

希望有帮助。