0

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"
  }]
}

此查询的真正含义是以下哪项?

  1. 文档应包含attrs.name = usernameORattrs.value = johndoe
  2. 或者,文档应该同时包含attrs.name = usernameAND attrs.value = johndoe,即使它们可能匹配数组中的不同元素attrs(这意味着上面给出的文档将匹配查询)
  3. 或者,文档应该同时包含attrs.name = usernameAND attrs.value = johndoe,但它们必须匹配数组中的相同元素attrs(这意味着上面给出的文档与查询不匹配)

此外,我如何编写一个查询来表达上面列表中的#3,即只有当数组中的单个元素同时满足以下两个条件时,文档才应该匹配:attrs

  • attrs.name = 用户名
  • attrs.value = johndoe
4

2 回答 2

2

Must代表“And”,因此返回满足匹配查询中所有子句的文档。

必须不满足第 1 点。文档应包含 attrs.name = username 或 attrs.value = johndoe - 您需要一个类似于“OR”的 should 子句

Must 是否满足第 2 点或第 3 点取决于“attrs”字段的类型。

如果“attr”字段类型是对象,那么字段将被展平,即在数组的不同字段之间没有关系。因此,如果有任何 attrs.name="username" 和 attrs.value="John doe",则必须查询将返回一个文档,即使它们不是该数组中同一对象的一部分。

如果您希望数组中的对象充当单独的文档,则需要使用嵌套字段并使用嵌套查询来匹配文档

{
  "query": {
    "nested": {
      "path": "attrs",
      "inner_hits": {}, --> returns matched nested documents
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "attrs.name": "username"
              }
            },
            {
              "match": {
                "attrs.value": "johndoe"
              }
            }
          ]
        }
      }
    }
  }
}

响应中的命中将包含所有嵌套文档,要获取所有匹配的嵌套文档,必须指定 inner_hits

于 2020-05-28T10:19:58.237 回答
0

根据您需要将attrs字段定义为嵌套的要求,请参阅Elasticsearch 中的嵌套类型以获取更多信息。免责声明:它维护了这种关系,但查询成本很高。

回答您的其他两个问题也取决于您使用的数据类型,请参阅嵌套与对象数据类型了解更多详细信息

编辑:使用示例映射的解决方案、示例文档和预期结果

使用嵌套类型的索引映射

{
    "mappings": {
        "properties": {
            "attrs": {
                "type": "nested"
            }
        }
    }
}

索引 2 示例文档 1 符合标准,其他不符合标准

{
    "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"
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        ]
于 2020-05-28T10:14:34.527 回答