如何过滤具有数组且具有多于N个元素的字段的文档?
如何过滤具有空数组字段的文档?
方面是解决方案吗?如果是这样,怎么样?
答案 0 :(得分:51)
我会看一下script filter。以下过滤器应仅返回fieldname
字段中至少包含10个元素的文档,该字段是一个数组。请记住,这可能会很昂贵,具体取决于索引中包含的文档数量。
"filter" : {
"script" : {
"script" : "doc['fieldname'].values.length > 10"
}
}
关于第二个问题:那你真的有一个空阵列吗?或者它只是一个没有值的数组字段?您可以使用missing filter获取对特定字段没有价值的文档:
"filter" : {
"missing" : { "field" : "user" }
}
否则我猜你需要再次使用脚本,类似于我上面提到的,只是输入的长度不同。如果长度是常量,我会把它放在params
部分,这样脚本将被elasticsearch缓存并重复使用,因为它始终是相同的:
"filter" : {
"script" : {
"script" : "doc['fieldname'].values.length > param1"
"params" : {
"param1" : 10
}
}
}
答案 1 :(得分:12)
javanna的回答在Elasticsearch 1.3.x及更早版本中是正确的,因为1.4默认脚本模块已更改为groovy(mvel)。
回答OP的问题。
在Elasticsearch 1.3.x及更早版本中,请使用以下代码:
"filter" : {
"script" : {
"script" : "doc['fieldname'].values.length > 10"
}
}
在Elasticsearch 1.4.x及更高版本中,使用以下代码:
"filter" : {
"script" : {
"script" : "doc['fieldname'].values.size() > 10"
}
}
此外,在Elasticsearch 1.4.3及更高版本中,由于安全性问题,您需要启用动态脚本,因为默认情况下已禁用该脚本。请参阅:https://www.elastic.co/guide/en/elasticsearch/reference/1.4/modules-scripting.html
答案 2 :(得分:6)
Imho使用脚本按大小过滤数组的正确方法是:
"filter" : {
"script" : {
"script" : "_source.fieldName.size() > 1"
}
}
如果我这样做,因为@javanna建议它抛出异常groovy.lang.MissingPropertyException: No such property: length for class: java.lang.String
答案 3 :(得分:5)
还在这里贴出与我相同情况的人。 假设您的数据如下所示:
{
"_source": {
"fieldName" : [
{
"f1": "value 11",
"f2": "value 21"
},
{
"f1": "value 12",
"f2": "value 22"
}
]
}
}
然后过滤fieldName
长度>例如1:
"query": {
"bool" : {
"must" : {
"script" : {
"script" : {
"inline": "doc['fieldName.f1'].values.length > 1",
"lang": "painless"
}
}
}
}
}
脚本语法与ES 5.4文档https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html一样。
答案 4 :(得分:4)
依赖于里萨克的回答。
有size()函数返回列表的长度:
"filter" : {
"script" : {
"script" : "doc['fieldname'].values.size() > 10"
}
}
答案 5 :(得分:2)
最简单的方法是对数据进行“非规范化”,以便拥有包含计数的属性和布尔值(如果存在或不存在)。然后你可以搜索这些属性。
例如:
{
"id": 31939,
"hasAttachments": true,
"attachmentCount": 2,
"attachments": [
{
"type": "Attachment",
"name": "txt.txt",
"mimeType": "text/plain"
},
{
"type": "Inline",
"name": "jpg.jpg",
"mimeType": "image/jpeg"
}
]
}
答案 6 :(得分:2)
如果您有未映射为nested
的 object 数组,请记住Elastic会将其展平为:
attachments: [{size: 123}, {size: 456}] --> attachments.size: [123, 456]
因此,您要将字段引用为doc['attachments.size'].length
,而不是doc['attachments'].length
,这很违反直觉。
与doc.containsKey(attachments.size)
相同。
.values
部分已弃用,不再需要。
答案 7 :(得分:1)
当您需要查找包含某些字段的文档时,该字段的大小/长度应该更大,然后零@javanna给出了正确的答案。我只想添加如果您的字段是文本字段,并且您想查找包含该字段中某些文本的文档,则不能使用相同的查询。您将需要执行以下操作:
GET index/_search
{
"query": {
"bool": {
"must": [
{
"range": {
"FIELD_NAME": {
"gt": 0
}
}
}
]
}
}
}
这不是对这个问题的确切答案,因为答案已经存在,但是我已经解决了类似问题,所以也许有人会觉得有用。
答案 8 :(得分:0)
关于第二个问题的建议:
<块引用>如何过滤包含空数组字段的文档?
{
"query": {
"bool": {
"must_not": {
"exists": {
"field": "fieldname"
}
}
}
}
}
将返回带有空 fieldname: []
数组的文档。 must
(而不是 must_not
会返回相反的结果)。