首页 > 解决方案 > 如何使用 query_string 同时匹配嵌套和非嵌套字段?

问题描述

我有一个带有如下映射的索引:

"email" : {
  "type" : "nested",
  "properties" : {
    "from" : {
      "type" : "text",
      "analyzer" : "lowercase_keyword",
      "fielddata" : true
    },
    "subject" : {
      "type" : "text",
      "analyzer" : "lowercase_keyword",
      "fielddata" : true
    },
    "to" : {
      "type" : "text",
      "analyzer" : "lowercase_keyword",
      "fielddata" : true
    }
  }
},
"textExact" : {
  "type" : "text",
  "analyzer" : "lowercase_standard",
  "fielddata" : true
}

我想query_string同时在嵌套和非嵌套字段中搜索匹配项,例如

email.to:foo@example.com AND textExact:bar

但我不知道如何编写一个同时搜索两个字段的查询。以下不起作用,因为query_string搜索不返回嵌套文档

"query": {
  "query_string": {
    "fields": [
      "textExact",
      "email.to"
    ],
    "query": "email.to:foo@example.com AND textExact:bar"
  }
}

我可以编写一个单独的嵌套查询,但这只会搜索嵌套字段。有什么方法可以query_string同时匹配嵌套和非嵌套字段?

我正在使用 Elasticsearch 6.8。在 Elasticsearch 论坛上交叉发布。

标签: elasticsearch

解决方案


嵌套文档只能使用嵌套查询进行查询。

您可以遵循以下两种方法。

1.你可以在must子句中结合嵌套查询和普通查询,对于不同的查询,它的作用类似于“and”。

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "email",
            "query": {
              "term": {
                "email.to": "foo@example.com"
              }
            }
          }
        },
        {
          "match": {
            "textExact": "bar"
          }
        }
      ]
    }
  }
}

2.复制到

copy_to 参数允许您将多个字段的值复制到一个组字段中,然后可以将其作为单个字段进行查询。

{
  "mappings": {
    "properties": {
      "textExact":{
        "type": "text"
      },
      "to_email":{
        "type": "keyword"
      },
      "email":{
        "type": "nested",
        "properties": {
          "to":{
            "type":"keyword",
            "copy_to": "to_email"  --> copies to non-nested field
          },
          "from":{
            "type":"keyword"
          }
        }
      }
    }
  }
}

询问

{
  "query": {
    "query_string": {
      "fields": [
        "textExact",
        "to_email"
      ],
      "query": "to_email:foo@example.com AND textExact:bar"
    }
  }
}

结果

"_source" : {
          "textExact" : "bar",
          "email" : [
            {
              "to" : "sdfsd@example.com",
              "from" : "a@example.com"
            },
            {
              "to" : "foo@example.com",
              "from" : "sdfds@example.com"
            }
          ]
        }

推荐阅读