多值数据的弹性搜索查询

时间:2017-08-31 15:58:58

标签: elasticsearch elasticsearch-dsl

ES数据的索引如下:

 {
  "addresses" : [
                {
                 "id" : 69,
                 "location": "New Delhi"
                },
               {
               "id" : 69,
               "location": "Mumbai"
               }
            ],
  "goods" : [
            {
            "id" : 396,
            "name" : "abc",
            "price" : 12500
            },
           {
           "id" : 167,
           "name" : "XYz",
           "price" : 12000
           },
           {
            "id" : 168,
            "name" : "XYz1",
            "price" : 11000
           },
           {
            "id" : 169,
            "name" : "XYz2",
            "price" : 13000
          }
        ]
      }

在我的查询中,我想要获取至少应该包含一个地址匹配且商品价格范围介于11000和13000之间且名称为xyz的记录。

1 个答案:

答案 0 :(得分:0)

当您的数据包含复杂对象的数组(如地址列表或商品列表)时,您可能需要查看elasticsearch的{​​{1}}对象,以避免在查询结果时遇到问题比你期望的更多的项目。

这里的问题是elasticsearch(以及lucene)存储数据的方式。由于没有直接嵌套对象列表的这种概念,因此数据被展平并且例如在nestedXYz丢失了。因此,当您查询12000XYz时,您也会收到此文档,因为12500的价格也在12500的值列表中。为了避免这种情况,您可以使用elasticsearch的{​​{1}}对象功能,它基本上将所有内部对象提取为隐藏索引,并允许查询在一个特定对象中出现的多个字段,而不是在任何对象中查找" #34 ;.有关详细信息,请查看the docs on nested objects,这也解释了这一点非常好。

在您的情况下,映射可能如下所示。我假设,您只想在不提供id的情况下查询goods.price文本,以便此列表可以保持为简单对象类型,而不是嵌套类型。另外,我假设您查询完全匹配。如果不是这种情况,您需要从nested切换到addresses.location并将keyword查询调整为text一个......

term

然后,您可以使用match上的bool查询和嵌套查询来匹配PUT nesting-sample { "mappings": { "item": { "properties": { "addresses": { "properties": { "id": {"type": "integer"}, "location": {"type": "keyword"} } }, "goods": { "type": "nested", "properties": { "id": {"type": "integer"}, "name": {"type": "keyword"}, "price": {"type": "integer"} } } } } } } 列表的内部文档。

location

此查询与文档不匹配,因为价格范围与商品的确切名称不在同一嵌套对象中。如果您将下限更改为goods,它将匹配。

请检查您的使用案例,并了解有关the mapping explosion when using nested fields的文档底部的警告。