我在应用程序中使用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的列表。上面的代码完全错误,我不熟悉如何执行此操作的语法。任何帮助将不胜感激。
答案 0 :(得分:2)
在希望查询对象属性的属性的场景中需要嵌套类型。举个例子,
如果您只想查询listItemID
上的listItems
lineItems
,那么object
type就可以正常使用。
如果您想在listItemID
上查询itemName
的{{1}} 和 listItems
,则需要映射{{ 1}}作为nested
type.
这样做的原因是,在不使用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_analyzed
或term
),您可以将其包装在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