我是 ES 中的一个新 bie,我想使用脚本过滤器来获取数组至少有一个元素小于 max 和大于 min 的所有匹配项(max 和 min 是脚本中的参数)。
该文档如下所示:
{
"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'] }
几件事:
- 你的脚本只是遍历一个集合并检查一个条件,不返回布尔值,这就是你想要的
- 您可以考虑将
number
的映射更改为integer
类型 - 不太确定为什么您有一个字段
array
并且其中有一个嵌套字段key
.难道你就不能有一个领域array
那就是......和阵列?;-) - 请记住,默认情况下,在 ES 中,每个字段可以是单个值或数组。
- 正如@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
]
}
}
]
}
}