我是Elasticsearch的新手,我正在尝试创建一个过滤器来检索具有特定属性的文档。
属性在映射中定义为嵌套对象,如下所示:
"attributes": {
"type": "nested",
"properties" : {
"id": {
"type": "integer"
},
...
}
}
}
我试图以以下形式执行复杂查询:
(attribute.id == 1 OR attribute.id == 2) AND (attribute.id == 3 OR attribute.id == 4)
根据我到目前为止所读到的内容,我已经创建了以下查询:
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"nested": {
"path": "attributes",
"filter": {
"bool": {
"must": [
{ "bool" : {
"should" : [
{ "term": { "attributes.id": 1 }},
{ "term": { "attributes.id": 2 }}
]
}},
{ "bool" : {
"should" : [
{ "term": { "attributes.id": 3 }},
{ "term": { "attributes.id": 4 }}
]
}}
]
}
}
}
}
}
},
"sort": {
"date": { "order": "desc" }
}
}
然而,这不会返回任何结果。如果我删除bools
块中的两个must
之一,则会正确过滤文档。
如果我将查询(出于测试目的)更改为:
,则存在相同的问题(无结果)"must": [
{ "term": { "attributes.id": 3 }},
{ "bool" : {
"should" : [
{ "term": { "attributes.id": 1 }},
{ "term": { "attributes.id": 2 }}
]
}}
]
我的理解转化为attributes.id == 3 AND (attributes.id == 1 OR attributes.id == 2)
这是elasticsearch 2.x.我做错了什么?
答案 0 :(得分:3)
为了获得您要查找的结果,您需要执行两个单独的nested
个查询,并使用bool
查询将它们链接在一起。
以下是一个例子:
{
"bool":{
"must":[
{
"nested":{
"path":"attributes",
"filter":{
"bool":{
"should":[
{ "term": {"attributes.id": 1 }},
{ "term": {"attributes.id": 2 }}
]
}
}
}
},
{
"nested":{
"path":"attributes",
"filter":{
"bool":{
"should":[
{ "term": {"attributes.id": 3 }},
{ "term": {"attributes.id": 4 }}
]
}
}
}
}
]
}
}
原因在于嵌套文档和嵌套查询的细微差别。看一下documentation on nested queries的部分内容:
对嵌套对象/文档执行查询,就像它们一样 被索引为单独的文档(它们是内部的)并导致 根父文档(或父嵌套映射)。
执行nested
查询时,您实际上并未对根文档执行查询(尽管感觉那样)。该查询针对嵌套文档进行操作,就像它们是单独的文档一样。
因此,当您查询两者 id =(1或2)AND id =(3或4)的嵌套文档时,您将得不到任何结果。在您的数据中,每个嵌套文档只有这些id值中的一个。