Elasticsearch.Net查询使用NEST和嵌套对象来检索文档

时间:2017-01-30 20:08:21

标签: c# nested nest elasticsearch-net

我在应用程序中使用Elasticsearch.Net和NEST,并且在基于嵌套对象ID搜索时无法访问Elasticsearh索引中的文档。数据结构是发票 - > lineItems - > rowItems。我想基于这些rowItems Id进行搜索。索引的(简化)映射是:

POST /_search
{
  "query": {
    "bool": {
      "should": [
        {"match": {
            "lineItems.rowItems.rowItemID" : "23f2157f-eb21-400d-b3a1-a61cf1451262"            
        }} 
      ]
    }
  }
}

当我在某个嵌套对象的chrome中搜索时,我可以成功检索它:

            var result = Execute(client => client.Search<Invoice>(s => s
    .Aggregations(a => a
        .Nested("my_nested_agg", n => n
            .Path("lineItems")
            .Aggregations(aa => aa
                .Filter("my_avg_agg", avg => avg
                    .Field(p => searchIds.Contains(p.LineItems.First().RowItems.First().TrackingItemID))
                )
            )
        )
    )
));

返回文档类型Invoice及其所有详细信息。

我一直在玩这个使用NEST执行此操作的代码但到目前为止已经失败了。我有一个rowItemIds列表,我想获得所有与这些ID完全匹配的发票文档。这就是我目前所拥有的:

{{1}}

其中searchIds是我搜索的rowItemIds的列表。上面的代码完全错误,我不熟悉如何执行此操作的语法。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:2)

在希望查询对象属性的属性的场景中需要嵌套类型。举个例子,

  1. 如果您只想查询listItemID上的listItems lineItems,那么object type就可以正常使用。

  2. 如果您想在listItemID上查询itemName的{​​{1}} listItems,则需要映射{{ 1}}作为nested type.

  3. 这样做的原因是,在不使用lineItems类型的情况下,索引时不会存储特定listItems的属性之间的关联。使用nested类型,存储关联(listItem类型在内部存储为文档)。

    您拥有的搜索查询在NEST中非常相似;在这种情况下,nested查询不需要包含在nested查询match子句中

    bool

    获取字段名称的lambda表达式就是这样; 表达式以获取字段名称

    这会生成查询

    should

    由于var client = new ElasticClient(); var searchResponse = client.Search<Invoice>(s => s .AllIndices() .AllTypes() .Query(q => q .Match(m => m .Field(f => f.LineItems.First().ListItems.First().ListItemID) .Query("23f2157f-eb21-400d-b3a1-a61cf1451262") ) ) ); POST http://localhost:9200/_search { "query": { "match": { "lineItems.listItems.listItemID": { "query": "23f2157f-eb21-400d-b3a1-a61cf1451262" } } } } 字符串字段,因此您可以在此处使用listItemID查询,因为您可能不需要计算得分(匹配在这种情况下是not_analyzedterm),您可以将其包装在true查询false子句中,该子句可以利用过滤器缓存并应该执行稍好一点。

    要获取与id集合匹配的文档,我们可以使用bool查询

    filter

    最后,使用一元terms运算符

    var ids = new[] { "23f2157f-eb21-400d-b3a1-a61cf1451262", "23f2157f-eb21-400d-b3a1-a61cf1451263", "23f2157f-eb21-400d-b3a1-a61cf1451264" }; var searchResponse = client.Search<Invoice>(s => s .AllIndices() .AllTypes() .Query(q => q .Terms(m => m .Field(f => f.LineItems.First().ListItems.First().ListItemID) .Terms(ids) ) ) ); 查询bool子句中包装它的简写
    filter