elasticsearch根据作为数组的字段的大小进行过滤

era*_*ran 50 elasticsearch

如何过滤具有字段且具有多于N个元素的字段的文档?

如何过滤具有空数组字段的文档?

方面是解决方案吗?如果是这样,怎么样?

jav*_*nna 54

我会看一下脚本过滤器.以下过滤器应仅返回fieldname字段中至少包含10个元素的文档,即阵列.请记住,这可能很昂贵,具体取决于索引中包含的文档数量.

"filter" : {
    "script" : {
        "script" : "doc['fieldname'].values.length > 10"
    }
}
Run Code Online (Sandbox Code Playgroud)

关于第二个问题:那你真的有一个空阵列吗?或者它只是一个没有值的数组字段?您可以使用缺少的过滤器来获取对于特定字段没有任何价值的文档:

"filter" : {
    "missing" : { "field" : "user" }
}
Run Code Online (Sandbox Code Playgroud)

否则我猜你需要再次使用脚本,类似于我上面提到的,只是输入不同的长度.如果长度是常量,我会把它放在params部分中,这样脚本将被elasticsearch缓存并重用,因为它总是相同的:

"filter" : {
    "script" : {
        "script" : "doc['fieldname'].values.length > param1"
        "params" : {
            "param1" : 10
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果该字段是字符串而不是数组,您知道如何执行此操作吗?我试过 `"script": "doc['title'].value.length() > 10"` 但没有运气...... (2认同)
  • 我有同样的问题,该字段是一个数组,但 ES 将其视为字符串,因此它抛出 `groovy.lang.MissingPropertyException: No such property: length for class: java.lang.String` (2认同)

小智 14

javanna的答案在Elasticsearch 1.3.x及更早版本中是正确的,因为1.4默认脚本模块已更改为groovy(mvel).

回答OP的问题.

在Elasticsearch 1.3.x及更早版本中,使用以下代码:

"filter" : {
    "script" : {
        "script" : "doc['fieldname'].values.length > 10"
    }
}
Run Code Online (Sandbox Code Playgroud)

在Elasticsearch 1.4.x及更高版本中,使用以下代码:

"filter" : {
    "script" : {
        "script" : "doc['fieldname'].values.size() > 10"
    }
}
Run Code Online (Sandbox Code Playgroud)

此外,在Elasticsearch 1.4.3及更高版本中,由于安全性问题,您需要启用动态脚本,因为它已默认禁用.请参阅:https://www.elastic.co/guide/en/elasticsearch/reference/1.4/modules-scripting.html


lis*_*sak 6

Imho使用脚本按大小过滤数组的正确方法是:

"filter" : {
    "script" : {
        "script" : "_source.fieldName.size() > 1"
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我这样做,因为@javanna建议抛出异常 groovy.lang.MissingPropertyException: No such property: length for class: java.lang.String

  • 原因是`Groovy` 为数组和字符串都提供了`size()`。如果不是 _all_ 您的值是数组,那么您将遇到您所做的问题,因为您试图在不存在的字符串上使用长度 _property_。 (3认同)
  • 源比doc慢得多,它会击中磁盘. (2认同)

use*_*787 6

如果您有一组未映射为 的对象nested,请记住 Elastic 会将它们展平为:

attachments: [{size: 123}, {size: 456}] --> attachments.size: [123, 456]
Run Code Online (Sandbox Code Playgroud)

所以你想将你的字段引用为doc['attachments.size'].length,而不是doc['attachments'].length,这是非常违反直觉的。

对于 也一样doc.containsKey(attachments.size)

.values部件已弃用,不再需要。


Tha*_*gTD 5

还在这里贴出了与我相同情况的人.假设您的数据如下所示:

{
    "_source": {
        "fieldName" : [
            {
                "f1": "value 11",
                "f2": "value 21"
            },
            {
                "f1": "value 12",
                "f2": "value 22"
            }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

然后过滤fieldName长度> 1,例如:

"query": {
    "bool" : {
        "must" : {
            "script" : {
                "script" : {
                    "inline": "doc['fieldName.f1'].values.length > 1",
                    "lang": "painless"
                 }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

脚本语法为ES 5.4文档https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html.

  • `doc['fieldName.f1'].length > 2` 在 es 7.x 上工作正常 (5认同)