【问题标题】:Elastic Search querying a nested and parent attribute queryElastic Search 查询嵌套和父属性查询
【发布时间】:2019-10-11 13:35:55
【问题描述】:

我有一个弹性文档,如下所示。

{
  "process_id" : "123",
  "user_info" : [{
     "first_name":"A",
     "last_name: "B"
   }]
}

{
  "process_id" : "123",
  "user_info" : [{
     "first_name":"C",
     "last_name: "B"
 }, 
  {"first_name" : "A", 
  "last_name":"D"
  } ]
}

场景 1:

我没有将嵌套类型设置为“user_info”字段。 我搜索“process_id”为 123,first_name 为 A,last_name 为 B,我得到了结果中的两个文件。

场景 2:

搜索返回错误。看起来我将无法搜索嵌套项和父项中的项。

查询如下:

{


 "query": {
    "query_string": {
      "query": "process_id:123",
      "nested": {
        "path": "user_info",
        "query": {
          "query_string": {
            "query": "(user_info.first_name:A AND user_info.last_name:B"
          }
        }
      }
    }   } }

错误响应如下。

{
"error": {
"root_cause": [
{
"type": "parsing_exception",
"reason": "[query_string] unknown token [START_OBJECT] after [nested]",
"line": 1
}
],
"type": "parsing_exception",
"reason": "[query_string] unknown token [START_OBJECT] after [nested]",
"line": 1,

},
"status": 400
}

理想的响应应该是当我搜索process_id为123,first_name为A,last_name为B时,只需要返回第一个文档。

注意:属性名称保持通用,以便说明实际情况。

【问题讨论】:

  • 请添加您正在尝试执行的搜索及其引发的错误。
  • @KevinQuinzel 更新了我在查询中收到的查询和错误响应

标签: elasticsearch elasticsearch-query


【解决方案1】:

我可以在您的场景 2 中看到以下 2 个问题

  • 要组合查询,您需要使用bool-query
  • 为了使nested-queries 工作,您需要将“父”字段定义为nested-field

1.在映射中将字段 user_info 声明为 nested 类型:

PUT processes
{
  "mappings": {
    "properties": {
      "process_id": {
        "type": "keyword"
      },
      "user_info": {
        "type": "nested",
        "properties": {
          "first_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "last_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

注意:user_info 的映射与额外的行 "type": "nested"

2。索引您提供的 2 个示例文档

POST processes/_bulk
{"index":{"_id":1}}
{"process_id": "123", "user_info": [{"first_name": "A", "last_name": "B"}]}
{"index":{"_id":2}}
{"process_id": "123", "user_info": [{"first_name": "C", "last_name": "B"},{"first_name": "A", "last_name": "D"}]}

3.使用nested-query 查询first_namelast_name 的组合

GET processes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "process_id": {
              "value": "123"
            }
          }
        },
        {
          "nested": {
            "path": "user_info",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "user_info.first_name": "A"
                    }
                  },
                  {
                    "match": {
                      "user_info.last_name": "B"
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

注意: search_request 搜索与 process_id (123) 以及 user_info.first_nameuser_info.last_name 的组合匹配一个特定用户(而不是跨用户)的所有文档。在上述设置中,查询仅匹配文档 1。 如果您希望 Elasticsearch 也告诉您是哪个 user_info 导致了匹配(如果一个进程有多个 user_info 对象),您可以在嵌套查询中添加以下子句:"inner_hits": {}

您可能想知道为什么我将字段process_id 映射到keyword 字段。这是最佳实践,因为keyword 是存储 ID 的最有效类型。

Elasticsearch 文档中的参考:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-nested-query.html

2019 年 10 月 13 日更新:添加了使用 queryString-query 的版本

GET processes/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "query_string": {
            "query": "process_id:123"
            }
        },
        {
          "nested": {
            "path": "user_info",
            "query": {
              "query_string": {
                "query": "user_info.first_name:A AND user_info.last_name:B"
              }
            }
          }
        }
      ]
    }
  }
}

【讨论】:

  • 谢谢丹尼尔!会尝试让你知道。我已经将父字段定义为嵌套。是否可以使用 bool query by query_string 来实现您所说明的内容?
  • Elasticsearch query string-query 是一个常规的 Elasticsearch 查询,可以在可以使用其他查询的任何地方使用。 query string-query 在其查询参数中接受 Lucene-query 语法,它不像 Elasticsearch 的 Query DSL 那样功能丰富。我使用querystring-query 更新了示例代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-24
  • 1970-01-01
  • 1970-01-01
  • 2019-08-11
  • 1970-01-01
相关资源
最近更新 更多