ES 嵌套对象数据问题

发布于:2024-03-29 ⋅ 阅读:(17) ⋅ 点赞:(0)
一,数据结构
"properties": {
    "type": { "type": "keyword" } ,
    "title": { "type": "text", "analyzer": "ik_smart" }, 
    "long_title": { "type": "text", "analyzer": "ik_smart" }, 
    "category_id": { "type": "integer" },
    "category": { "type": "keyword" },
    "category_path": { "type": "keyword" },
    "description": { "type": "text", "analyzer": "ik_smart" },
    "price": { "type": "scaled_float", "scaling_factor": 100 },
    "on_sale": { "type": "boolean" },
    "rating": { "type": "float" },
    "sold_count": { "type": "integer" },
    "review_count": { "type": "integer" },
    "skus": {
      "type": "nested",
      "properties": {
        "title": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_title" }, 
        "description": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_description" },
        "price": { "type": "scaled_float", "scaling_factor": 100 }
      }
    },
    "properties": {
      "type": "nested",
      "properties": {
        "name": { "type": "keyword" }, 
        "value": { "type": "keyword", "copy_to": "properties_value" }
      }
    }
  }
二,场景

分面查询条件

{
						"nested": {
							"path": "properties",
							"query": [
								{
									"term": {
										"properties.name": "外包装颜色"
									}
								},
								{
									"term": {
										"properties.value": "白色"
									}
								}
							]
						}
					}

我想要的结果是外包装属性值为白色的产品,结果会多出来另外一个属性机器颜色也是白色的产品。
原因是 ES 对于json对象数组的做了压扁处理,比如上面的例子在 ES真实 存储的结构是这样的

[
    "properties" => [
        "name"  => ["外包装颜色", "机器颜色"],
        "value" => ["白色", "黑色"]
    ]
]

很明显,这样的结构丢失了属性名称和属性值的关联,导致查询的时候,出现失效,如果业务要求实现精准搜索,那么这种方案是不满足要求的。我使用新增一个字段,来解决这个问题,当然还有别的方法可以解决(详见此文章

"properties": {
    "type": { "type": "keyword" } ,
    "title": { "type": "text", "analyzer": "ik_smart" }, 
    "long_title": { "type": "text", "analyzer": "ik_smart" }, 
    "category_id": { "type": "integer" },
    "category": { "type": "keyword" },
    "category_path": { "type": "keyword" },
    "description": { "type": "text", "analyzer": "ik_smart" },
    "price": { "type": "scaled_float", "scaling_factor": 100 },
    "on_sale": { "type": "boolean" },
    "rating": { "type": "float" },
    "sold_count": { "type": "integer" },
    "review_count": { "type": "integer" },
    "skus": {
      "type": "nested",
      "properties": {
        "title": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_title" }, 
        "description": { "type": "text", "analyzer": "ik_smart", "copy_to": "skus_description" },
        "price": { "type": "scaled_float", "scaling_factor": 100 }
      }
    },
    "properties": {
      "type": "nested",
      "properties": {
        "name": { "type": "keyword" }, 
        "value": { "type": "keyword", "copy_to": "properties_value" },
        "search_value": { "type": "keyword" }
      }
    }
  }

新增一个search_value ,把属性名和属性值拼接之后存入这个字段,然后在筛选时也将属性名和属性值拼接,并精确匹配 search_value 字段即可。

本文含有隐藏内容,请 开通VIP 后查看