ElasticSearch 数组数据将嵌套元素中的多个属性与 AND 条件匹配



我遇到了一个问题,我有两个文档,每个文档包含一个对象数组。我喜欢搜索一个包含嵌套对象的两个属性的文档(在同一对象中同时匹配两个属性),但我总是得到两个文档。

我创建了文档:

POST /respondereval/_doc
{
"resp_id": "1236",
"responses": [
{"key": "meta","text":"abc"},
{"key": "property 1", "text": "yes"},
{"key": "property 2", "text": "yes"},
]
}
POST /respondereval/_doc
{
"resp_id": "1237",
"responses": [
{"key": "meta","text":"abc"},
{"key": "property 1", "text": "no"},
{"key": "property 2", "text": "yes"},
]
}

我为它们定义了一个索引,以防止 ES 像这样平整对象:

PUT /respondereval
{
"mappings" : {
"properties": {
"responses" : {
"type": "nested"
}
}
}
}

我现在想使用以下查询搜索第一个文档(resp_id 1236):

GET /respondereval/_search
{
"query": {
"nested": {
"path": "responses",
"query": {
"bool": {
"must": [
{ "match": { "responses.key": "property 1" } },
{ "match": { "responses.text": "yes" } }
]
}
}
}
}
}

这应该只返回一个同时匹配两个条件的元素。

不幸的是,它总是返回两个文档。我认为这是因为在某些时候,ES 仍然将嵌套对象数组中的值扁平化为如下所示(简化):

resp_id 1236: "key":["gender", "property 1", "property 2"], "text:["abc", "yes", "yes"]
resp_id 1237: "key":["gender", "property 1", "property 2"], "text:["abc", "no", "yes"]

两者都包含property1yes

解决这个问题的正确方法是什么,以便只返回包含对象数组中同时匹配两个条件("key": "property 1" AND "text": "yes")的元素的文档?

问题出在您的映射上。您有默认使用标准分析器的文本映射。

标准分析器在空格上创建令牌。所以

property 1将被标记为

{
"tokens": [
{
"token": "property",
"start_offset": 0,
"end_offset": 8,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "1",
"start_offset": 9,
"end_offset": 10,
"type": "<NUM>",
"position": 1
}
]
}

同样property 2也是如此。

因此,两个文档都将返回。

当您搜索yes时,它与第二个文档中的第二个文本匹配。property 1匹配文档中第二个密钥property分析令牌。

要使其工作: - 使用keyword变体

{
"query": {
"nested": {
"path": "responses",
"query": {
"bool": {
"must": [
{ "match": { "responses.key.keyword": "property 1" } },
{ "match": { "responses.text.keyword": "yes" } }
]
}
}
}
}
}

这将是正确的:

{
"query": {
"nested": {
"path": "responses",
"query": {
"bool": {
"must": [
{ "match_phrase": { "responses.key": "property 1" } },//phrase queries
{ "match": { "responses.text": "yes" } }
]
}
}
}
}
}

您是否直接尝试了没有nested.pathmust查询

{
"query": {
"bool": {
"must": [
{
"match": {
"responses.key": "property 1"
}
},
{
"match": {
"responses.text": "yes"
}
}
]
}
}
}

最新更新