我在这里有一个问题。在常见的购物车网站中,功能搜索具有多个过滤器的产品。例如,我正在寻找带有这样一些过滤器的运动装备:
制造商
选项
这是我的映射
PUT test/product/_mapping
{
"product":{
"properties" : {
"name" : {"type" : "string", "store":"yes"},
"manufacturer" {"type": "string}
"options" : {
"type": "nested"
}
}
}
}
一些测试数据
POST test/product/1
{
"name": "Shirt 1",
"manufacturer": "Adidas",
"options":[
{
"Color" : ["Red", "Green"]
},
{
"Size" : ["S","M","L"]
}
],
"price":250000
}
POST test/product/2
{
"name": "Shirt 2",
"manufacturer": "Nike",
"options":[
{
"Color" : ["Blue", "Green", "White"]
},
{
"Size" : ["S", "L", "XL"]
}
],
"price":100000
}
POST test/product/3
{
"name": "Shirt 3",
"manufacturer": "Umbro",
"options": [
{
"Color" : ["Red"]
},
{
"Size" : ["S","XXL"]
}
],
"price": 300000
}
有了这个查询,一切都很好
POST test/product/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "options",
"filter": {
"bool": {
"must": [
{
"terms": {
"options.Color": [
"white"
]
}
}
]
}
}
}
},
{
"term": {
"manufacturer": "nike"
}
}
]
}
}
}
}
}
但是,如果我在选项过滤器中添加更多条件,则无法获得结果
POST test/product/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"nested": {
"path": "options",
"filter": {
"bool": {
"must": [
{
"terms": {
"options.Color": [
"white"
]
}
},
{
"terms": {
"options.Size": [
"s"
]
}
}
]
}
}
}
},
{
"term": {
"manufacturer": "nike"
}
}
]
}
}
}
}
}
我不知道我在映射或查询中是否错了,或者您能告诉我在这种情况下创建映射的最佳方法是什么。谢谢你的帮助。
答案 0 :(得分:1)
这里的问题是nested
类型的使用。您的nested
过滤器不会对所有孩子进行评估,而是针对每个孩子进行单独评估。由于您没有单个嵌套对象,因此满足您的过滤器(同时具有Color
和Size
),您无法获得任何结果。您有两种选择:
将这些单独的嵌套对象合并在一起
POST test/product/1
{
"name": "Shirt 1",
"manufacturer": "Adidas",
"options":[
{
"Color" : ["Red", "Green"],
"Size" : ["S","M","L"]
}
],
"price":250000
}
您的地图和查询保持不变。
请勿使用nested
类型,而应使用简单的object
类型。您必须更改options
的映射:
PUT test/product/_mapping
{
"product":{
"properties" : {
"options" : {
"type": "object"
}
}
}
}
然后删除nested
过滤器:
POST test/product/_search
{
"query": {
"filtered": {
"query": {
"match_all": {}
},
"filter": {
"bool": {
"must": [
{
"terms": {
"options.Color": [
"white"
]
}
},
{
"terms": {
"options.Size": [
"s"
]
}
},
{
"term": {
"manufacturer": "nike"
}
}
]
}
}
}
}
}
但您的数据可以保持不变。
嵌套对象实际上适用于不同的结构化数据。如果你有像
这样的东西"options":[
{
"Color" : "Blue",
"Size": "S"
},
{
"Color": "Red",
"Size" : "L"
}
]
并且您希望过滤项目, Blue 和 S ,然后您必须使用嵌套过滤器。