Eva*_*tis 6 elasticsearch nest
假设我已将以下文档编入索引:
[
{
"Id": 1,
"Numbers": [1, 2, 3]
},
{
"Id": 2,
"Numbers": [4, 5]
}
]
Run Code Online (Sandbox Code Playgroud)
我有一个参数[1,2,4,5],它定义了哪些数字我不被允许看到 - 我想找到文件,其中"Numbers"数组包含至少一个不在我的输入数组中的元素(所以在这种情况下)应该返回第一份文件).
真实场景是查找哪些(或谁的子组)不包含属于某种产品类型的产品的组.我递归索引产品类型ID(在示例中表示为数字),我想找到包含不属于我的输入参数的产品的组(我的输入参数是产品类型ID的数组,我不允许看到)
我应该使用哪个查询/过滤器以及如何构建它?我考虑过以下几点:
return desc.Bool(b => b
.MustNot(mn => mn.Bool(mnb => mnb.Must(mnbm => mnbm.Terms(t => t.ItemGroups, permissions.RestrictedItemGroups) && mnbm.Term(t => t.ItemGroupCount, permissions.RestrictedItemGroups.Count())))));
Run Code Online (Sandbox Code Playgroud)
但问题是如果我有6个受限制的项目组,其中给定的组包含3个受限制的组,那么我将找不到任何匹配项,因为计数将不匹配.这现在有点意义.作为一种解决方法,我在C#中实现了Results.Except(Restricted)以在搜索后过滤掉受限制的组,但是我希望在elasticsearch中实现它.
新答案
我将离开下面的旧答案,因为它可能对其他人有用.在您的情况下,您希望过滤掉不匹配的文档,而不仅仅标记它们.因此,以下查询将为您提供您所期望的,即只有第一个文档:
POST test/_search
{
"query": {
"script": {
"script": {
"source": """
// copy the doc values into a temporary list
def tmp = new ArrayList(doc.Numbers.values);
// remove all ids from the params
tmp.removeIf(n -> params.ids.contains((int)n));
// return true if the array still contains ids, false if not
return tmp.size() > 0;
""",
"params": {
"ids": [
1,
2,
4,
5
]
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
较老的答案
解决此问题的一种方法是使用脚本字段,该字段将根据您的条件返回true或false:
POST test/_search
{
"_source": true,
"script_fields": {
"not_present": {
"script": {
"source": """
// copy the numbers array
def tmp = params._source.Numbers;
// remove all ids from the params
tmp.removeIf(n -> params.ids.contains(n));
// return true if the array still contains data, false if not
return tmp.length > 0;
""",
"params": {
"ids": [ 1, 2, 4, 5 ]
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果如下所示:
"hits" : {
"total" : 2,
"max_score" : 1.0,
"hits" : [
{
"_index" : "test",
"_type" : "doc",
"_id" : "2",
"_score" : 1.0,
"_source" : {
"Id" : 2,
"Numbers" : [
4,
5
]
},
"fields" : {
"not_present" : [
false <--- you don't want this doc
]
}
},
{
"_index" : "test",
"_type" : "doc",
"_id" : "1",
"_score" : 1.0,
"_source" : {
"Id" : 1,
"Numbers" : [
1,
2,
3
]
},
"fields" : {
"not_present" : [
true <--- you want this one, though
]
}
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
112 次 |
| 最近记录: |