使用 Nest 客户端将嵌套的 属性 复制到 elasticsearch 中的父对象

Copying a nested property to parent object in elasticsearch with Nest client

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

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

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

鉴于下面的对象,我想将 'Street' 从一个人的地址 属性 复制到 'Search' 属性 的人

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

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

将'LastName'映射到'Search'很简单,如下所示。

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

这是您可以做到的方法

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>访问PersonSearch属性,要么用一个字符串。

搜索returns预期文件

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

copy_to 字段不一定需要在 C# POCO 上公开为 属性,因为 _source 不会包含它们的值。然而,公开为 属性 可能对强类型字段访问有用。