我有以下结构(简化):
{
"id": 100,
"vendorStatuses": [
{
"id": 200,
"status": "Open"
}
]
}
我想要找的是没有供应商状态的记录。我们最近从elasticseach 1.x升级到5.x,但我无法转换为恢复此功能。
我的旧Nest查询如下所示:
!Filter<PurchaseOrder>.Nested(nfd => nfd.Path(x => x.VendorStatuses.First())
.Filter(f2 => f2.Missing(y => y.Id)));
新查询(现在Missing
不可用)到目前为止看起来像这样:
Query<PurchaseOrder>
.Bool(z => z
.MustNot(a => a
.Exists(t => t
.Field(f => f.VendorStatuses)
)
)
);
产生这个:
GET purchaseorder/_search
{
"query": {
"bool": {
"must_not": [
{
"exists": {
"field": "vendorStatuses",
}
}
]
}
}
}
但我仍然看到有vendorStatuses
条记录的结果。
我做错了什么?我已经尝试搜索vendorStatuses.id
或其他字段,但它无效。当我尝试颠倒逻辑并执行must
时,我看不到任何结果。我也尝试过这样做nested
,但无法与之相提并论。
答案 0 :(得分:1)
使用must_not
和exists
的查询不是像{x}查询那样的nested
查询。我想你正在寻找像
var query = Query<PurchaseOrder>
.Bool(z => z
.MustNot(a => a
.Nested(n => n
.Path(p => p.VendorStatuses)
.Query(nq => nq
.Exists(t => t
.Field(f => f.VendorStatuses)
)
)
)
)
);
client.Search<PurchaseOrder>(s => s.Query(_ => query));
产生
{
"query": {
"bool": {
"must_not": [
{
"nested": {
"query": {
"exists": {
"field": "vendorStatuses"
}
},
"path": "vendorStatuses"
}
}
]
}
}
}
您可以使用operator overloading使查询更简洁
var query = !Query<PurchaseOrder>
.Nested(n => n
.Path(p => p.VendorStatuses)
.Query(nq => nq
.Exists(t => t
.Field(f => f.VendorStatuses)
)
)
);
答案 1 :(得分:0)
在我看来,我发现了一种远非理想的解决方法。我在我的PurchaseOrder
模型上为NumberOfStatuses
创建了一个新属性,然后我只对0
的值进行了术语搜索。
public int NumberOfStatuses => VendorStatuses.OrEmptyIfNull().Count();
Query<PurchaseOrder>.Term(t => t.Field(po => po.NumberOfStatuses).Value(0));