Elasticsearch-数组上的脚本过滤器 [英] Elasticsearch - Script filter on array

查看:284
本文介绍了Elasticsearch-数组上的脚本过滤器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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).

文件类似:

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

谢谢大家。

推荐答案

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

Yes it's doable, your script is not doing that, though. Try using Groovy's any() method instead:

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

一些事情:


  1. 您的脚本只是遍历一个集合并检查条件,不返回布尔值,而这就是您想要的

  2. 您可以考虑将数字的映射更改为整数类型

  3. 不太确定为什么要有一个字段 array ,并在其中有一个嵌套字段 key 。您难道没有一个 array 字段是...和数组吗? ;-)

  4. 请记住,默认情况下,在ES中,每个字段可以是单个值或数组。

  5. 正如@Val所提到的,您需要在您的 conf / elasticsearch.yml 中启用动态脚本,但我想您已经完成了,否则您将获得例外。

  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
  3. not really sure why you have a field array and inside it a nested field key. Couldn't you just have a field array that would be... and array? ;-)
  4. remember that in ES by default each field can be a single value or an array.
  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.

像这样的非常简单的映射应该起作用:

A very simple mapping like this should work:

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

这篇关于Elasticsearch-数组上的脚本过滤器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆