"must" 子句与 "match" 子句数组的真正含义是什么?
How does "must" clause with an array of "match" clauses really mean?
我有一个 elasticsearch query
看起来像这样...
"query": {
"bool": {
"must": [{
"match": {"attrs.name": "username"}
}, {
"match": {"attrs.value": "johndoe"}
}]
}
}
... 索引中的文档如下所示:
{
"key": "value",
"attrs": [{
"name": "username",
"value": "jimihendrix"
}, {
"name": "age",
"value": 23
}, {
"name": "alias",
"value": "johndoe"
}]
}
这个查询 really 是什么意思?
- 文档应包含
attrs.name = username
或 attrs.value = johndoe
- 或者,文档应同时包含
attrs.name = username
和 attrs.value = johndoe
,即使它们可能与 attrs
数组中的 不同元素 匹配(这意味着上面给出的文档将 匹配 查询)
- 或者,文档应同时包含
attrs.name = username
和 attrs.value = johndoe
,但它们必须与 attrs
数组中的 相同元素 相匹配(这意味着上面给出的文档 不匹配 查询)
此外, 我如何编写一个查询来表达上面列表中的#3,即只有 单个元素[=49 时文档才应该匹配=] 在 attrs
数组中匹配 both 以下条件:
- attrs.name = 用户名
- attrs.value = johndoe
根据您的要求,您需要将 attrs
字段定义为嵌套,请参阅 nested type in Elasticsearch 了解更多信息。 免责声明:它维护关系但查询成本高。
其他两个问题的答案也取决于您使用的数据类型,请参阅 nested vs object data type 了解更多详情
编辑:使用示例映射、示例文档和预期结果的解决方案
使用嵌套类型的索引映射
{
"mappings": {
"properties": {
"attrs": {
"type": "nested"
}
}
}
}
索引 2 示例文档,其中一个符合标准,另一个不符合标准
{
"attrs": [
{
"name": "username",
"value": "johndoe"
},
{
"name": "alias",
"value": "myname"
}
]
}
另一个服务标准
{
"attrs": [
{
"name": "username",
"value": "jimihendrix"
},
{
"name": "age",
"value": 23
},
{
"name": "alias",
"value": "johndoe"
}
]
}
和搜索查询
{
"query": {
"nested": {
"path": "attrs",
"inner_hits": {},
"query": {
"bool": {
"must": [
{
"match": {
"attrs.name": "username"
}
},
{
"match": {
"attrs.value": "johndoe"
}
}
]
}
}
}
}
}
和搜索结果
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "2",
"_score": 1.7509375,
"_source": {
"attrs": [
{
"name": "username",
"value": "johndoe"
},
{
"name": "alias",
"value": "myname"
}
]
},
"inner_hits": {
"attrs": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.7509375,
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "2",
"_nested": {
"field": "attrs",
"offset": 0
},
"_score": 1.7509375,
"_source": {
"name": "username",
"value": "johndoe"
}
}
]
}
}
}
}
]
必须代表"And"所以满足匹配查询中所有子句的文档是returned .
必须不满足第 1 点。文档应包含 attrs.name = 用户名或 attrs.value = johndoe- 您需要一个 should 子句,其工作方式类似于 "OR"
Must 是否满足第 2 点或第 3 点取决于 "attrs" 字段的类型。
如果 "attr" 字段类型是 object 则字段被展平,即数组的不同字段之间没有关系。因此,如果有 attrs.name="username" 和 attrs.value="John doe",则必须查询 return 文档,即使它们不是该数组中同一对象的一部分。
如果你想让一个数组中的对象像一个单独的文档一样,你需要使用nested field and use nested query来匹配文档
{
"query": {
"nested": {
"path": "attrs",
"inner_hits": {}, --> returns matched nested documents
"query": {
"bool": {
"must": [
{
"match": {
"attrs.name": "username"
}
},
{
"match": {
"attrs.value": "johndoe"
}
}
]
}
}
}
}
}
响应中的命中将包含所有嵌套文档,要获取所有匹配的嵌套文档,必须指定 inner_hits
我有一个 elasticsearch query
看起来像这样...
"query": {
"bool": {
"must": [{
"match": {"attrs.name": "username"}
}, {
"match": {"attrs.value": "johndoe"}
}]
}
}
... 索引中的文档如下所示:
{
"key": "value",
"attrs": [{
"name": "username",
"value": "jimihendrix"
}, {
"name": "age",
"value": 23
}, {
"name": "alias",
"value": "johndoe"
}]
}
这个查询 really 是什么意思?
- 文档应包含
attrs.name = username
或attrs.value = johndoe
- 或者,文档应同时包含
attrs.name = username
和attrs.value = johndoe
,即使它们可能与attrs
数组中的 不同元素 匹配(这意味着上面给出的文档将 匹配 查询) - 或者,文档应同时包含
attrs.name = username
和attrs.value = johndoe
,但它们必须与attrs
数组中的 相同元素 相匹配(这意味着上面给出的文档 不匹配 查询)
此外, 我如何编写一个查询来表达上面列表中的#3,即只有 单个元素[=49 时文档才应该匹配=] 在 attrs
数组中匹配 both 以下条件:
- attrs.name = 用户名
- attrs.value = johndoe
根据您的要求,您需要将 attrs
字段定义为嵌套,请参阅 nested type in Elasticsearch 了解更多信息。 免责声明:它维护关系但查询成本高。
其他两个问题的答案也取决于您使用的数据类型,请参阅 nested vs object data type 了解更多详情
编辑:使用示例映射、示例文档和预期结果的解决方案
使用嵌套类型的索引映射
{
"mappings": {
"properties": {
"attrs": {
"type": "nested"
}
}
}
}
索引 2 示例文档,其中一个符合标准,另一个不符合标准
{
"attrs": [
{
"name": "username",
"value": "johndoe"
},
{
"name": "alias",
"value": "myname"
}
]
}
另一个服务标准
{
"attrs": [
{
"name": "username",
"value": "jimihendrix"
},
{
"name": "age",
"value": 23
},
{
"name": "alias",
"value": "johndoe"
}
]
}
和搜索查询
{
"query": {
"nested": {
"path": "attrs",
"inner_hits": {},
"query": {
"bool": {
"must": [
{
"match": {
"attrs.name": "username"
}
},
{
"match": {
"attrs.value": "johndoe"
}
}
]
}
}
}
}
}
和搜索结果
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "2",
"_score": 1.7509375,
"_source": {
"attrs": [
{
"name": "username",
"value": "johndoe"
},
{
"name": "alias",
"value": "myname"
}
]
},
"inner_hits": {
"attrs": {
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.7509375,
"hits": [
{
"_index": "nested",
"_type": "_doc",
"_id": "2",
"_nested": {
"field": "attrs",
"offset": 0
},
"_score": 1.7509375,
"_source": {
"name": "username",
"value": "johndoe"
}
}
]
}
}
}
}
]
必须代表"And"所以满足匹配查询中所有子句的文档是returned .
必须不满足第 1 点。文档应包含 attrs.name = 用户名或 attrs.value = johndoe- 您需要一个 should 子句,其工作方式类似于 "OR"
Must 是否满足第 2 点或第 3 点取决于 "attrs" 字段的类型。
如果 "attr" 字段类型是 object 则字段被展平,即数组的不同字段之间没有关系。因此,如果有 attrs.name="username" 和 attrs.value="John doe",则必须查询 return 文档,即使它们不是该数组中同一对象的一部分。
如果你想让一个数组中的对象像一个单独的文档一样,你需要使用nested field and use nested query来匹配文档
{
"query": {
"nested": {
"path": "attrs",
"inner_hits": {}, --> returns matched nested documents
"query": {
"bool": {
"must": [
{
"match": {
"attrs.name": "username"
}
},
{
"match": {
"attrs.value": "johndoe"
}
}
]
}
}
}
}
}
响应中的命中将包含所有嵌套文档,要获取所有匹配的嵌套文档,必须指定 inner_hits