在 elasticsearch 中针对多个值查询嵌套对象属性
Query Nested Object properties against multiple values in elasticsearch
假设我们有嵌套的对象注释,其中包含两个属性标记和组。如果我执行以下查询,那么它会给我想要的结果。
{
"query": {
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": {
"match": {
"comment.tag": {
"query": "SPRING",
"type": "boolean"
}
}
},
"must_not": {
"match": {
"comment.group": {
"query": "ABC",
"type": "boolean"
}
}
}
}
},
"path": "comment"
}
}
}
}
}
但是如果我执行下面的查询,它不会给我想要的结果。
{
"query": {
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": {
"match": {
"comment.tag": {
"query": [
"SPRING",
"HIBERNATE"
],
"type": "boolean"
}
}
},
"must_not": {
"match": {
"comment.group": {
"query": [
"ABC",
"XYZ"
],
"type": "boolean"
}
}
}
}
},
"path": "comment"
}
}
}
}
}
这两者之间的区别在于,我针对多个值查询嵌套对象的两个属性。
对于第二个查询,它仅选取提供给搜索的列表中的最后一个值和 returns 结果。
有没有一种方法可以编写查询,我可以在其中指定传递值列表并且所有值都包含在搜索中?
这与嵌套无关query/filter。相反,它是您使用 match
query 的方式。它不需要值数组。
实际上有两种方法可以实现您似乎正在尝试的目标。在进入它们之前,我确实想注意 match
查询默认使用 boolean
类型,因此您可以忽略它。
您可以更改 match
查询以简单地在字符串中提供两个值。顺序无关紧要:
"bool" : {
"must" : {
"match" : {
"comment.tag" : "SPRING HIBERNATE"
}
}
}
之所以可行,是因为该字段将使用搜索分析器以与对该字段建立索引(默认)的方式相同的方式来标记字符串。因此,假设使用默认的字符串分析器,您最终将搜索 spring
或 hibernate
。因为您没有使用词组匹配,所以顺序确实无关紧要。
另一种方法是使用外部 bool
/must
查询显式分隔它们(同样适用于 must_not
和 should
).因为你希望他们像 OR
s 一样对待,所以你需要使用 should
而不是 must
这样:
"bool" : {
"should" : [
{
"match" : { "company.tag" : "SPRING" }
},
{
"match" : { "company.tag" : "HIBERNATE" }
}
]
}
注意:如果您还包括 must
,则需要将 minimum_should_match
设置为 1(在 bool
对象内部),这样它就不会成为可选的。没有 must
和 must_not
,它隐式为 1.
假设我们有嵌套的对象注释,其中包含两个属性标记和组。如果我执行以下查询,那么它会给我想要的结果。
{
"query": {
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": {
"match": {
"comment.tag": {
"query": "SPRING",
"type": "boolean"
}
}
},
"must_not": {
"match": {
"comment.group": {
"query": "ABC",
"type": "boolean"
}
}
}
}
},
"path": "comment"
}
}
}
}
}
但是如果我执行下面的查询,它不会给我想要的结果。
{
"query": {
"bool": {
"must": {
"nested": {
"query": {
"bool": {
"must": {
"match": {
"comment.tag": {
"query": [
"SPRING",
"HIBERNATE"
],
"type": "boolean"
}
}
},
"must_not": {
"match": {
"comment.group": {
"query": [
"ABC",
"XYZ"
],
"type": "boolean"
}
}
}
}
},
"path": "comment"
}
}
}
}
}
这两者之间的区别在于,我针对多个值查询嵌套对象的两个属性。
对于第二个查询,它仅选取提供给搜索的列表中的最后一个值和 returns 结果。
有没有一种方法可以编写查询,我可以在其中指定传递值列表并且所有值都包含在搜索中?
这与嵌套无关query/filter。相反,它是您使用 match
query 的方式。它不需要值数组。
实际上有两种方法可以实现您似乎正在尝试的目标。在进入它们之前,我确实想注意 match
查询默认使用 boolean
类型,因此您可以忽略它。
您可以更改
match
查询以简单地在字符串中提供两个值。顺序无关紧要:"bool" : { "must" : { "match" : { "comment.tag" : "SPRING HIBERNATE" } } }
之所以可行,是因为该字段将使用搜索分析器以与对该字段建立索引(默认)的方式相同的方式来标记字符串。因此,假设使用默认的字符串分析器,您最终将搜索
spring
或hibernate
。因为您没有使用词组匹配,所以顺序确实无关紧要。另一种方法是使用外部
bool
/must
查询显式分隔它们(同样适用于must_not
和should
).因为你希望他们像OR
s 一样对待,所以你需要使用should
而不是must
这样:"bool" : { "should" : [ { "match" : { "company.tag" : "SPRING" } }, { "match" : { "company.tag" : "HIBERNATE" } } ] }
注意:如果您还包括
must
,则需要将minimum_should_match
设置为 1(在bool
对象内部),这样它就不会成为可选的。没有must
和must_not
,它隐式为 1.