一尘不染

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

elasticsearch

如何在索引映射定义中将嵌套属性复制到包含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)
                        )
                    )
                )

但是我无法弄清楚将’Person.Address.Street’复制到’Person.Search’的Nest语法


阅读 402

收藏
2020-06-22

共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属性Person,或使用字符串。

搜索返回期望的文档

{
  "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"
          }
        }
      }
    ]
  }
}

copy_toElasticsearch中的字段不一定需要在C#POCO上作为属性公开,因为_source不会包含它们的值。但是,作为属性公开对于强类型字段访问可能很有用。

2020-06-22