【问题标题】:ElasticSearch: Finding documents with field value that is in an arrayElasticSearch:查找具有数组中字段值的文档
【发布时间】:2012-08-12 12:16:51
【问题描述】:

我有一些客户文档,我希望使用 ElasticSearch 根据客户的来源来检索这些文档(国家字段是 IN 一系列国家/地区)。

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

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

["DE", "FR", "IT"]

我想获取A2和A3这两个文件。

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

【问题讨论】:

    标签: python elasticsearch pyes


    【解决方案1】:

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

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

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

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

    国家:{ 类型:“字符串”, 索引:“未分析” }

    要查找带有DE 的文档,您可以:

    curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1'  -d '
    {
       "query" : {
          "constant_score" : {
             "filter" : {
                "term" : {
                   "country" : "DE"
                }
             }
          }
       }
    }
    '
    

    使用DEFR 查找文档:

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

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

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

    另请参阅此答案,了解对象数组如何变得棘手,因为它们是扁平化的:

    Is it possible to sort nested documents in ElasticSearch?

    【讨论】:

    • 哦,好吧...也许我的解释不清楚。提供的 sn-p 实际上是我通过弹性搜索从查询中得到的。我只是想通过按国家过滤来进一步细化查询。是否总是需要制作自己的自定义映射?我目前只是依赖 ElasticSearch 用来索引我的文档的默认动态映射。
    • 好的,这个问题并不清楚。关于制作自定义映射,不,您不必创建一个,但我强烈建议您这样做。这样你就可以确切地知道发生了什么——你不依赖于启发式方法。您的国家/地区字段目前正在被分析为全文,但它不是 - 它是一个枚举。在这种情况下,这可能没什么区别,但可能会导致稍后在其他领域出现奇怪的行为(取决于它们的内容)。创建映射很容易,并且是一个好习惯。
    • 嗯...谢谢您的回复。我想我不能偷懒。原因是我的 couchdb 文档是疯狂的大型嵌套结构....映射所有内容将是一件苦差事,而且我有 9 种不同类型的文档。
    猜你喜欢
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 2021-09-30
    相关资源
    最近更新 更多