【问题标题】:Search multiple indexes and return correct types搜索多个索引并返回正确的类型
【发布时间】:2019-11-15 08:53:59
【问题描述】:

我在 Elasticsearch 中设置了两个索引来存储不同类型的数据,我正在尝试同时从两个索引中使用嵌套获取搜索结果。我已经设置了如下模型...

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> ...

我看到的其他答案建议执行以下操作,但我认为 Types 函数已在 NEST 7.0 中删除...

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

【问题讨论】:

    标签: c# .net elasticsearch nest


    【解决方案1】:

    如果您可以控制文档索引,则可以利用 NEST 中的possibility to customize JSON serialization 进程,方法是将 .NET 类型放置在弹性搜索索引中的文档中。这样 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 包需要安装在你的项目中。

    希望对您有所帮助。

    【讨论】:

    • 效果很好!谢谢!我不得不稍微改变一下我们的流程,以便我们的索引是通过 NEST 创建的,因为手动添加 $type 字段似乎不起作用,但现在一切正常。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 2019-04-10
    相关资源
    最近更新 更多