Elasticsearch上的多个值的嵌套排序

时间:2017-04-18 16:43:48

标签: elasticsearch

我想使用多个值对嵌套的Elasticsearch进行排序。这是一个例子:

我有一些Events,它有一个嵌套的topics,就像这个

    "_source": {
      "topics": [
        {
          "type": "Tools",
          "name": "Data Science",
          "id": 19
        },
        {
          "type": "Challenges",
          "name": "Disaster Resilience",
          "id": 1
        },
        {
          "type": "Tools",
          "name": "Entrepreneurship",
          "id": 21
        },
        {
          "type": "Challenges",
          "name": "Prosperity",
          "id": 8
        }
      ]
      ...
    }

此外,Members具有相同的嵌套topics,使用相同的结构。

我想要做的是根据会员主题排序活动。例如,如果一个成员有三个匹配的主题与一个事件,两个匹配另一个,我想首先显示最匹配的事件。

我试过这样的事情:

"sort":[
      {
         "topics.id":{
            "nested_path":"topics",
            "mode":"sum",
            "order":"asc",
            "nested_filter":{       
              "match": {
                "topics.id": 13
              }
            }
         }
      }
   ]

适用于特定主题。但是我想在sort中使用多个值,首先返回匹配最多的事件,然后执行以下操作。在这种情况下,将首先返回带有主题13和14的事件,而不是仅包含主题13的事件,并且之后将显示所有其他不匹配的事件。

"sort":[
      {
         "topics.id":{
            "nested_path":"topics",
            "mode":"sum",
            "order":"asc",
            "nested_filter":[       
              {
                "match": {
                  "topics.id": 13
                }
              },
              {
                "match": {
                  "topics.id": 14
                }
              }
            ]
         }
      }
   ]

已编辑:以下是使用此最后一段时收到的错误:

{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "[field_sort] nested_filter doesn't support values of type: START_ARRAY"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "[field_sort] nested_filter doesn't support values of type: START_ARRAY"
  },
  "status": 400
}

但不幸的是,这不起作用。有没有办法做到这一点?我在这里错过了一些很棒的功能吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

我能够使用无痛脚本解决这个问题。如果这是性能方面的话,我不这样做,但是它正在发挥作用。如果我找到更好的解决方案,也会发布这个。

{
   "query":{
      "bool":{
         "must":[
            {
               "nested":{
                  "path":"topics",
                  "query":{
                     "function_score":{
                        "script_score":{
                           "script":{
                              "lang":"painless",
                              "params":{
                                 "ids":[
                                    1,
                                    14,
                                    19,
                                    13,
                                    19,
                                    21,
                                    8
                                 ]
                              },
                              "inline":"int s = 0; for (int i = 0; i < params.ids.length; i++){ for (int j = 0; j < doc['topics.id'].value; j++) { if (params.param1[i] == doc['topics.id'][j]) { s =+ 1 }}} return s"
                           }
                        }
                     }
                  }
               }
            }
         ]
      }
   }
}