当前位置: 首页 > 面试题库 >

Elasticsearch-数组上的脚本过滤器

鲜于光辉
2023-03-14
问题内容

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

该文件像:

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

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

谢谢你们。


问题答案:

是的,这是可行的,但是您的脚本没有这样做。尝试改用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但是我想您已经完成了,否则您将获得异常。

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

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


 类似资料:
  • 我有一个返回一组文档(100)的查询。我想对这些应用一个聚合,因为这些是最相关的。当我尝试聚合时,它返回所有结果的聚合,而不是前100个结果的聚合。

  • 我有一个带有嵌套数据的ES索引,它是这样映射的 我想创建一个对两个(原始)值进行筛选的查询。我可以创建一个筛选器,对这些值之一进行筛选,如下所示: 然而,我需要的是这样的东西: 第一个查询有效,第二个查询引发错误: 嵌套:QueryParsingException[[ocm][nested]筛选器不支持[null]]; 如何创建匹配多个路径中的字段的筛选器?

  • 问题内容: 这是我的文件 我想在数组字段“ b”中找到元素并更新整个对象。我尝试了此脚本,但它没有更新。有任何想法吗? 问题答案: 使用此代替:

  • 问题内容: 我有一点阵。我想根据某些位是ON还是OFF进行过滤。查看Elasticsearch 2.3文档,我没有看到有关位数组的任何信息。 但似乎我可以使用布尔数组或二进制字段。 示例:假设我有2个文档,每个文档都有一个位数组字段。Doc1在该字段中具有011100,而Doc2具有00001。我想按011000进行过滤,在这种情况下,它仅给出Doc1。 任何想法如何在Elasticsearch中

  • 问题内容: 我正在尝试对数组中的值进行聚合,并且还过滤由前缀返回的存储桶。不知道这是否可行,或者我滥用过滤桶。 3份文件: 目的是获取带有字母B开头颜色的文档数量: 不幸的是,返回的结果包括Red。显然是因为带有红色的文档仍然按过滤器匹配,因为它们也具有蓝色和/或黑色。 有没有一种方法可以只过滤存储桶结果? 问题答案: 尝试此操作,它将过滤为存储桶本身创建的值:

  • 问题内容: 我有一个包含整数数组的字段,例如: 我想过滤结果,以使价格至少包含介于以下之间的值列表之一: 由于价格字段中的`[20002,30000] 问题答案: Elasticsearch始终认为字段可以包含值列表,因此,范围过滤器应该起作用。如果任何值与范围匹配,它将被过滤。 您可以将该过滤器用作过滤查询的一部分: 但是,过滤查询在2.0中已弃用,因此,如果您使用的是2.0,则最好将布尔查询与