ElasticSearch比较范围结果

时间:2016-03-20 16:09:10

标签: elasticsearch indexing range-query

您好我想索引看起来像

的对象
{
   uuid: "123",
   clauses: [{ order: 1, uuid: "345"},{ order: 2, uuid: "567"},{ order: 3, uuid: "789"}]

}

有没有办法编写一个匹配所有包含对象的查询 与uuid的条款:" 345"和uuid:" 789"但是第二个的顺序最多比第一个大两个?

所以上面的例子会匹配,但下一个例子不会:

 {
   uuid: "999",
   clauses: [{ order: 1, uuid: "345"},{ order: 2, uuid: "567"},{order: 3, uuid: "777"},{ order: 4, uuid: "789"}]

}

原因是" 789"子句是4,大于2大于" 345"条款,订单1。

任何帮助表示赞赏! 谢谢, 米凯尔

1 个答案:

答案 0 :(得分:1)

实现此目标的一种方法是使用script filter

我正在使用的脚本如下:

def idxs = []; 
for (int i = 0; i < doc['clauses.uuid'].values.size(); i++) {
    if (matches.contains(doc['clauses.uuid'].values[i])){
        idxs << i
    }
};
def orders = idxs.collect{ doc['clauses.order'].values[it]}; 
return orders[1] - orders[0] <= 2

基本上,我正在做的是首先收集uuid数组中包含matches的子句的所有索引(即345和789)。 然后,根据我得到的索引,我收集了那些索引处的所有order值。最后,我检查第二个order减去第一个order是否大于2。

POST your_index/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "clauses.uuid": "345"
          }
        },
        {
          "term": {
            "clauses.uuid": "789"
          }
        },
        {
          "script": {
            "script": "def idxs = []; for (int i = 0; i < doc['clauses.uuid'].values.size(); i++) {if (matches.contains(doc['clauses.uuid'].values[i])){idxs << i}}; def orders = idxs.collect{doc['clauses.order'].values[it]}; return orders[1] - orders[0] <= 2",
            "params": {
              "matches": [
                "345",
                "789"
              ]
            }
          }
        }
      ]
    }
  }
}

这将只返回第一个文档,而不是第二个文档。