我有以下对象:
[{
"some_field": "some_value",
"nested_objects": [{
"some_field2": "some_value",
"nested_objects2": [{
"some_field": "some_value",
"bool_field": true
}, {
"some_field": "some_value",
"bool_field": true
}, {
"some_field": "some_value",
"bool_field": false
}]
}, {
"some_field2": "some_value",
"nested_objects2": [{
"some_field": "some_value",
"bool_field": false
}, {
"some_field": "some_value",
"bool_field": false
}]
}]
},
{
"some_field": "some_value",
"nested_objects": [{
"some_field2": "some_value",
"nested_objects2": [{
"some_field": "some_value",
"bool_field": false
}, {
"some_field": "some_value",
"bool_field": false
}, {
"some_field": "some_value",
"bool_field": true
}]
}]
}
]
所有嵌套对象都映射为嵌套对象。我想根据第三级子级bool值对顶级父级进行排序。具有更多bool值的儿童应该排名高于其他儿童。
所以我基本上想按
排序_source.nested_objects.nested_objects2.bool_field
具有更多真实值的对象应该排名高于其他对象。
我还希望能够过滤嵌套对象,如:
_source.nested_objects.some_field == "some specific value"
然后,分数计算应仅应用于匹配的对象和匹配的嵌套对象。
这可能吗?
答案 0 :(得分:0)
当我最初阅读你的问题时,我认为甚至不可能超越第一级嵌套。幸运的是,我能够找到this论坛帖子,引导我找到可能的解决方案。
我想评论一下,我相信您可以更好地重新调整数据结构。规范化数据并执行伪“连接”以计算值可能是一种选择。
另一个选择(以及我将学习的那个)将是控制一个数值(在索引时用这些对象传递的某种类型的计数变量),或者包含一个在索引时为你计算这个值的脚本时间。在索引时执行此计算将允许您避免此相对昂贵的脚本的重复成本。
无论你在哪里,我认为以下内容应符合你目前的目标:
POST /test/_search
{
"query": {
"match_all": {}
},
"sort": [
{
"_script":{
"type":"number",
"script": {
"lang": "painless",
"source": "int bool_sum = 0;for(int i = 0; i < params._source.nested_objects.length;i++){for(def j = 0; j < params._source.nested_objects[i].nested_objects2.length; j++){if(params._source.nested_objects[i].nested_objects2[j].bool_field == true)bool_sum++;}}return bool_sum;"
}
}
}
]
}
令人讨厌的小脚本格式化为更清晰的阅读:
int bool_sum = 0;
for(int i = 0; i < params._source.nested_objects.length;i++)
for(def j = 0; j < params._source.nested_objects[i].nested_objects2.length; j++){
if(params._source.nested_objects[i].nested_objects2[j].bool_field == true)
bool_sum++;
return bool_sum;
我根据您的评论对此进行了更新,以便您使用输入参数进行比较:
POST /test/_search
{
"query": {
"match": {
"nested_objects.nested_objects2.bool_field": true
}
},
"sort": [
{
"_script": {
"type": "number",
"script": {
"params": {
"value_to_match": false
},
"lang": "painless",
"source": "int bool_sum = 0;for(int i = 0; i < params._source.nested_objects.length;i++){for(def j = 0; j < params._source.nested_objects[i].nested_objects2.length; j++){if(params._source.nested_objects[i].nested_objects2[j].bool_field == params.value_to_match )bool_sum++;}}return bool_sum;"
}
}
}
]
}
更新的脚本:
int bool_sum = 0;
for(int i = 0; i < params._source.nested_objects.length;i++)
for(def j = 0; j < params._source.nested_objects[i].nested_objects2.length; j++){
if(params._source.nested_objects[i].nested_objects2[j].bool_field == params.value_to_match)
bool_sum++;
return bool_sum;
答案 1 :(得分:0)
我可能找到了有用的东西。我可以创建嵌套查询,并将嵌套对象的分数添加到父类,如:
{
"from": 0,
"size": 10,
"sort": [{
"_score": {
"order": "desc"
}
}],
"query": {
"bool": {
"must": [{
"nested": {
"query": {
"nested": {
"query": {
"term": {
"nested_objects.nested_objects2.bool_field": {
"value": true
}
},
"score_mode": "sum"
},
"path": "nested_objects.nested_objects2",
"score_mode": "sum",
}
},
"path": "nested_objects",
"score_mode": "sum",
}
}]
}
}
}
如果我理解正确,那么父母将根据匹配的嵌套对象得到更好的分数,父母得分越多,分数越高,匹配得越多。
这是对的吗?