在嵌套子

时间:2017-09-25 15:03:23

标签: elasticsearch

我有以下对象:

[{
        "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"

然后,分数计算应仅应用于匹配的对象和匹配的嵌套对象。

这可能吗?

2 个答案:

答案 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",
                }
            }]
        }
    }
}

如果我理解正确,那么父母将根据匹配的嵌套对象得到更好的分数,父母得分越多,分数越高,匹配得越多。

这是对的吗?