使用Nest Client在Elasticsearch中将嵌套属性复制到父对象

时间:2019-01-02 18:45:27

标签: elasticsearch nest

如何在索引映射定义中将嵌套属性复制到包含POCO的字段中?

当两个字段处于同一对象级别时,我可以使用.CopyTo 成功地将一个属性复制到另一个属性中。

但是我正在努力将嵌套对象的属性复制到父对象的属性。

鉴于以下对象,我想将“街道”从“人”的“地址”属性复制到“人”的“搜索”属性

Person
{
    public string Search { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

Address 
{
    public string Street { get; set; }
}

将“姓氏”映射到“搜索”很简单,如下所示。

.Map<Person>(map => map
                .AutoMap()
                .Properties(properties => properties
                .Text(text => 
                    text.Name(name => name.LastName)
                        .CopyTo(copyTo => 
                            copyTo.Field(field => field.Search)
                        )
                    )
                )

但是我无法弄清楚要复制的Nest语法 将“ Person.Address.Street”转换为“ Person.Search”

1 个答案:

答案 0 :(得分:1)

这是您的操作方式

private static void Main()
{
    var defaultIndex = "my_index";
    var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));

    var settings = new ConnectionSettings(pool)
        .DefaultIndex(defaultIndex);

    var client = new ElasticClient(settings);

    if (client.IndexExists(defaultIndex).Exists)
        client.DeleteIndex(defaultIndex);

    var createIndexResponse = client.CreateIndex(defaultIndex, c => c
        .Settings(s => s
            .NumberOfShards(1)
            .NumberOfReplicas(0)
        )
        .Mappings(m => m
            .Map<Person>(mm => mm
                .AutoMap()
                .Properties(p => p
                    .Object<Address>(o => o
                        .Name(n => n.Address)
                        .AutoMap()
                        .Properties(pp => pp
                            .Text(t => t
                                .Name(nn => nn.Street)
                                .CopyTo(co => co
                                    .Field(Infer.Field<Person>(ff => ff.Search))
                                )
                            )
                        )
                    )
                )
            )
        )
    );

    var indexResponse = client.Index(new Person
        {
            LastName = "foo",
            Address = new Address
            {
                Street = "bar"
            }
        } , i => i
        .Refresh(Refresh.WaitFor)
    );

    var searchResponse = client.Search<Person>(s => s
        .Query(q => q
            .Match(m => m
                .Field(f => f.Search)
                .Query("bar")
            )
        )
    );
}

public class Person
{
    public string Search { get; set; }
    public string LastName { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public string Street { get; set; }
}

本质上

  1. 自动映射Person属性
  2. Address上明确映射Person属性
  3. 自动映射Address属性
  4. 显式映射Street属性并设置CopyTo(...)。此时,泛型类型参数为Address类型,因此您需要使用Nest.Infer.Field<T>来访问Search的{​​{1}}属性,或使用字符串。 / li>

搜索返回预期的文档

Person
Elasticsearch中的

{ "took" : 2, "timed_out" : false, "_shards" : { "total" : 1, "successful" : 1, "skipped" : 0, "failed" : 0 }, "hits" : { "total" : 1, "max_score" : 0.2876821, "hits" : [ { "_index" : "my_index", "_type" : "person", "_id" : "5tQDEWgBrKRHlz9qAve8", "_score" : 0.2876821, "_source" : { "lastName" : "foo", "address" : { "street" : "bar" } } } ] } } 字段不必作为C#POCO上的属性公开,因为copy_to不会包含它们的值。但是,作为属性公开对于强类型字段访问可能很有用。