2017-04-18 63 views
4

我想使用多个值对嵌套的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,使用相同的结构。

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

我想是这样的:

"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 
} 

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

谢谢!

+0

这是什么?你能发布回复以及预期的回应吗? – user3775217

+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" 
          } 
         } 
        } 
        } 
       } 
      } 
     ] 
     } 
    } 
}