Elasticsearch - 数组上的脚本过滤器

时间:2016-03-09 07:15:58

标签: elasticsearch

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

文件如:

 {
  "number": "5",
  "array": {
    "key": [
      10,
      5,
      9,
      20
    ]
  }
}

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

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

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

谢谢大家。

1 个答案:

答案 0 :(得分:9)

是的,但是你的脚本不是这样做的。请尝试使用Groovy的any()方法:

doc['array.key'].values.any{ it -> it >= min + doc['number'] && it <= max + doc['number'] }

一些事情:

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

    {
        "mappings": {
            "document": {
                "properties": {
                    "value": {
                        "type": "integer"
                    },
                    "key": { 
                        "type": "integer"
                    }
                }
            }
        }
    }
    

    示例:

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

    查询:

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

    结果:

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