简体   繁体   English

Elasticsearch - 数组上的脚本过滤器

[英]Elasticsearch - Script filter on array

I'm a new bie in ES and I want to use script filter to get all match that the array has at least one element less than max and greater than min (max and min are param in the script). 我是ES中的新bie,我想使用脚本过滤器来获得所有匹配,即数组至少有一个小于max且大于min的元素(max和min是脚本中的param)。

The document like: 该文件如:

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

I tried the script but it does not work 我尝试了脚本,但它不起作用

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

There is no error message but the search result is wrong.Is there a way to iterate array field? 没有错误消息,但搜索结果是错误的。有没有办法迭代数组字段?

Thank you all. 谢谢你们。

Yes it's doable, your script is not doing that, though. 是的,这是可行的,但是你的脚本并没有这样做。 Try using Groovy's any() method instead: 尝试使用Groovy的any()方法代替:

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

A few things: 一些东西:

  1. Your script just goes over a collection and checks a condition, doesn't return a boolean value, and that's what you want 你的脚本只是遍历一个集合并检查一个条件,不会返回一个布尔值,这就是你想要的
  2. you might consider changing the mapping for number into an integer type 你可能会考虑更改为映射numberinteger类型
  3. not really sure why you have a field array and inside it a nested field key . 不确定为什么你有一个字段array ,里面有一个嵌套的字段key Couldn't you just have a field array that would be... and array? 难道你不能只有一个字段array ......和数组吗? ;-) ;-)
  4. remember that in ES by default each field can be a single value or an array. 请记住,在ES中,默认情况下,每个字段可以是单个值或数组。
  5. As @Val has mentioned you need to enable dynamic scripting in your conf/elasticsearch.yml but I'm guessing you've done it, otherwise you'd be getting exceptions. 正如@Val所说,你需要在你的conf/elasticsearch.yml elasticsearch.yml中启用动态脚本,但我猜你已经完成了,否则你会得到异常。

A very simple mapping like this should work: 像这样的非常简单的映射应该有效:

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

Example: 例:

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

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

Query: 查询:

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

Result: 结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM