ElasticSearch:查找具有数组中字段值的文档

Mar*_*ark 5 python elasticsearch pyes

我有一些客户文档,我希望根据客户的来源(国家/地区字段位于国家/地区数组中)使用 ElasticSearch 检索这些文档。

[
  {
    "name": "A1",
    "address": {
      "street": "1 Downing Street"
      "country": {
        "code": "GB",
        "name": "United Kingdom"
      }
    }
  },
  {
    "name": "A2",
    "address": {
      "street": "25 Gormut Street"
      "country": {
        "code": "FR",
        "name": "France"
      }
    }
  },
  {
    "name": "A3",
    "address": {
      "street": "Bonjour Street"
      "country": {
        "code": "FR",
        "name": "France"
      }
    }
  }
]
Run Code Online (Sandbox Code Playgroud)

现在,我的 Python 代码中有另一个数组:

["DE", "FR", "IT"]
Run Code Online (Sandbox Code Playgroud)

我想要获得 A2 和 A3 两份文件。

我该如何在 PyES/Query DSL 中编写这个?我应该为此使用 ExistsFilter 或 TermQuery 吗?ExistsFilter 似乎只检查字段是否存在,但不关心值。

DrT*_*ech 4

在 NoSQL 类型的文档存储中,您返回的只是文档,而不是文档的一部分。

您的要求:“我想获取两个文档,A2 和 A3。 ”意味着您需要单独索引每个文档,而不是作为另一个“父”文档内的数组。

如果您需要同时匹配父文档的值,country那么您需要对数据进行非规范化,并将父文档中的这些值也存储在每个子文档中。

完成上述操作后,查询就很简单了。我假设该country字段映射为:

国家/地区:{ 类型:“字符串”,索引:“not_analyzed” }

要查找带有 的文档DE,您可以执行以下操作:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "term" : {
               "country" : "DE"
            }
         }
      }
   }
}
'
Run Code Online (Sandbox Code Playgroud)

要使用DE或查找文档FR

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
{
   "query" : {
      "constant_score" : {
         "filter" : {
            "terms" : {
               "country" : [
                  "DE",
                  "FR"
               ]
            }
         }
      }
   }
}
'
Run Code Online (Sandbox Code Playgroud)

将上述内容与其他一些查询词结合起来:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
{
   "query" : {
      "filtered" : {
         "filter" : {
            "terms" : {
               "country" : [
                  "DE",
                  "FR"
               ]
            }
         },
         "query" : {
            "text" : {
               "address.street" : "bonjour"
            }
         }
      }
   }
}
'
Run Code Online (Sandbox Code Playgroud)

另请参阅此答案,了解对象数组如何因展平方式而变得棘手的解释:

是否可以在 ElasticSearch 中对嵌套文档进行排序?