使用NEST进行Elasticsearch如何根据孩子的属性搜索父母

问题描述

我正在尝试使用nesT对给定特定客户位置的客户进行简单搜索。 POCOS是:

class Customer
{
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Identifiers { get; set; }
    public string isIndividual { get; set; }
    public double Balance { get; set; }
    public List<CustomerLocation> Locations { get; set; }

class CustomerLocation
{
    public int CustomerLocationId { get; set; }
    public string StreetLine1 { get; set; }
    public string Streetline2 { get; set; }
    public string City { get; set; }
   
}

当前我正在使用此搜索例程-但却失败:

                        var searchResponse = _client.Search<Customer>(s => s
                   .Query(q => q
                        .HasChild<CustomerLocation >(hp => hp
                            .Query(qq => qq
                                .Match(m => m
                                    .Field(f => f.City )
                                    .Query(queryText)
                                )
                                
                            )
                         )
                     )
                   .Size(500)
                    );

提供的错误消息是:

System.Exception HResult = 0x80131500 Message =无效的搜索错误是: 无效的nesT响应是由POST上的失败(400)低级调用生成的:/ customers / _search?typed_keys = true

此API调用的审核记录:

  • [1] SniffOnStartup:参加:00:00:00.2448689
  • [2]嗅探成功:节点:http:// localhost:9200 /接收:00:00:00.2288784
  • [3] PingSuccess:节点:http://127.0.0.1:9200/参加了:00:00:00.0029899
  • [4] BadResponse:节点:http://127.0.0.1:9200/参加了:00:00:00.1639172

OriginalException:Elasticsearch.Net.ElasticsearchClientException:远程服务器返回错误:(400)错误的请求。。呼叫:状态代码400来自:POST / customers / _search?typed_keys = true。 ServerError:类型:search_phase_execution_exception原因:“所有分片均失败” ---> System.Net.WebException:远程服务器返回错误:(400)错误的请求。

在System.Net.HttpWebRequest.GetResponse() 在C:\ Users \ russc \ source \ elasticsearch-net \ src \ Elasticsearch.Net \ Connection \ HttpWebRequestConnection.cs:line 63

中的Elasticsearch.Net.HttpWebRequestConnection.Request [TResponse](RequestData requestData)

任何想法-非常感谢。

解决方法

客户和位置之间的关系不是Elasticsearch术语中的父子关系,这是使用the has_child query所必需的。

除非明确映射,否则Locations上的Customer属性将是object type mapping,这将使您能够做到

var queryText = "Sydney";

var searchResponse = client.Search<Customer>(s => s
    .Query(q => q
       .Match(m => m
           .Field(f => f.Locations.First().City)
           .Query(queryText)
       )
    )
    .Size(500)
);

注意f => f.Locations.First().City只是一个表达式,用于通过导航对象图以强类型方式构建JSON字段的路径。它不是的意思是“第一个地点的城市”,但评估为“任何地点的城市”。

这将生成以下查询

{
  "query": {
    "match": {
      "locations.city": {
        "query": "Sydney"
      }
    }
  },"size": 500
}

但是,使用给定的POCO结构,您可能需要跨多个位置属性进行搜索。在这种情况下,Locations应该显式映射为nested data type

当映射为嵌套数据类型时,查询将为

var queryText = "Sydney";

var searchResponse = client.Search<Customer>(s => s
    .Query(q => q
        .Nested(n => n
            .Path(p => p.Locations)
            .Query(nq => nq
                .Match(m => m
                    .Field(f => f.Locations.First().City)
                    .Query(queryText)
                )
            )
        )
    )
    .Size(500)
);