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的记录。
答案 0 :(得分:0)
当您的数据包含复杂对象的数组(如地址列表或商品列表)时,您可能需要查看elasticsearch的{{1}}对象,以避免在查询结果时遇到问题比你期望的更多的项目。
这里的问题是elasticsearch(以及lucene)存储数据的方式。由于没有直接嵌套对象列表的这种概念,因此数据被展平并且例如在nested
和XYz
丢失了。因此,当您查询12000
和XYz
时,您也会收到此文档,因为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的文档底部的警告。