Elasticsearch - 数组上的脚本过滤器

sam*_*sam 3 elasticsearch

我是ES中的新bie,我想使用脚本过滤器来获得所有匹配,即数组至少有一个小于max且大于min的元素(max和min是脚本中的param).

该文件如:

 {
  "number": "5",
  "array": {
    "key": [
      10,
      5,
      9,
      20
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

我尝试了脚本,但它不起作用

{
  "script": {
    "lang": "groovy",
    "params": {
      "max": 64,
      "min": 6
    },
    "script": "for(element in doc['array.key'].values){element>= min + doc['number'].value &&  element <=max + doc['number'].value}"
  }
}
Run Code Online (Sandbox Code Playgroud)

没有错误消息,但搜索结果是错误的.有没有办法迭代数组字段?

谢谢你们.

Mat*_*zyk 10

是的,这是可行的,但是你的脚本并没有这样做.尝试使用Groovy的any()方法代替:

doc['array.key'].values.any{ it -> it >= min + doc['number'] && it <= max + doc['number'] }
Run Code Online (Sandbox Code Playgroud)

一些东西:

  1. 你的脚本只是遍历一个集合并检查一个条件,不会返回一个布尔值,这就是你想要的
  2. 你可能会考虑更改为映射number到一个integer类型
  3. 不确定为什么你有一个字段array,里面有一个嵌套字段key.难道你不能只有一个字段array......和数组吗?;-)
  4. 请记住,在ES中,默认情况下,每个字段可以是单个值或数组.
  5. 正如@Val所说,你需要在你的身上启用动态脚本,conf/elasticsearch.yml但我猜你已经完成了,否则你会得到异常.

像这样的非常简单的映射应该有效:

{
    "mappings": {
        "document": {
            "properties": {
                "value": {
                    "type": "integer"
                },
                "key": { 
                    "type": "integer"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

例:

POST /documents/document/1
 {
  "number": 5,
    "key": [
      10,
      5,
      9,
      20
    ]
}

POST /documents/document/2
 {
  "number": 5,
    "key": [
      70,
      72
    ]
}
Run Code Online (Sandbox Code Playgroud)

查询:

GET /documents/document/_search
{
  "query": {
    "bool": {
      "filter": {
            "script": {
                "lang": "groovy",
                "params": {
                    "max": 64,
                    "min": 6
                },
                "script": "doc['key'].values.any{ it -> it >= min + doc['number'] && it <= max + doc['number'] }"
        }
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

结果:

{
   "took": 22,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 0,
      "hits": [
         {
            "_index": "documents",
            "_type": "document",
            "_id": "1",
            "_score": 0,
            "_source": {
               "number": 5,
               "key": [
                  10,
                  5,
                  9,
                  20
               ]
            }
         }
      ]
   }
}
Run Code Online (Sandbox Code Playgroud)