129、商城业务-商品上架- elasticsearch高级运维nested数据类型场景

对于es数据库:如果需要在es索引中一个字段下面存储的是数组类型,必须使用nested类型,如下面的字段

 

 

 我们添加一个索引

向ES添加商品属性映射

PUT product
{
    "mappings":{
        "properties": {
            "skuId":{
                "type": "long"
            },
            "spuId":{
                "type": "keyword"
            },
            "skuTitle": {
                "type": "text",
                "analyzer": "ik_smart"
            },
            "skuPrice": {
                "type": "keyword"
            },
            "skuImg":{
                "type": "keyword",
                "index": false,
                "doc_values": false
            },
            "saleCount":{
                "type":"long"
            },
            "hasStock": {
                "type": "boolean"
            },
            "hotScore": {
                "type": "long"
            },
            "brandId": {
                "type": "long"
            },
            "catalogId": {
                "type": "long"
            },
            "brandName": {
                "type": "keyword",
                "index": false,
                "doc_values": false
            },
            "brandImg":{
                "type": "keyword",
                 "index": false,
                "doc_values": false
            },
            "catalogName": {
                "type": "keyword",
                "index": false,
                "doc_values": false
            },
            "attrs": {
                "type": "nested",
                "properties": {
                    "attrId": {
                        "type": "long"
                    },
                    "attrName": {
                        "type": "keyword",
                        "index": false,
                        "doc_values": false
                    },
                    "attrValue": {
                        "type": "keyword"
                    }
                }
            }
        }
    }
}

上面标红的有两个地方是必须注意的

第一就是https://blog.csdn.net/weixin_32196893/article/details/119170745

参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/7.5/nested.html

举例

PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
在索引index中,存入user的数据,最终 es 会将上述数据,扁平化处理,实际存储如下这样子:
{
  "group" :        "fans",
  "user.first" : [ "alice", "john" ],
  "user.last" :  [ "smith", "white" ]
}
很明显,数据存储成这样子,丢失了first 和 last 之间关系。从这样的存储中,我们无法确定,first 为 “alice” 的对应的 last 是 “smith” 还是 “white”。

执行如下查询:

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}

查询到的结果:

{
  "took" : 205,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "my_index",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.5753642,
        "_source" : {
          "group" : "fans",
          "user" : [
            {
              "first" : "John",
              "last" : "Smith"
            },
            {
              "first" : "Alice",
              "last" : "White"
            }
          ]
        }
      }
    ]
  }
}

查询到一条数据,而这样的数据并不是我们想要的。因为通过 "first" 为 "Alice" 和 "last" 为 "Smith",不应该查询到数据。之所以查询到数据,是因为数组中存储的对象被扁平化处理了。

修改索引的mapping信息,将user数组的类型定义为 nested 并存入数据,重新执行检索。
————————————————

PUT my_index
{
  "mappings": {
    "properties": {
      "user": {
        "type": "nested" 
      }
    }
  }
}

PUT my_index/_doc/1
{
  "group" : "fans",
  "user" : [ 
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}

执行同样查询:

GET my_index/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "user.first": "Alice" }},
        { "match": { "user.last":  "Smith" }}
      ]
    }
  }
}

获取到的结果为空:

{
  "took" : 11,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

这样的结果才是我们想要的,这样防止了 frist 和 last 之间关系的丢失。

第二个关键的设置:

"skuImg":{
"type": "keyword",
"index": false,
"doc_values": false
},

https://www.icode9.com/content-4-1024817.html

doc_values用于字段的该字段的排序、聚合等功能。我们首先关注如何激活 doc values,只要开启 doc values 后,排序,分组,聚合的时候会自动使用 doc values 提速。在 ElasticSearch 中,doc values 默认是开启的,比较简单暴力,我们也可以酌情关闭一些不需要使用 doc values 的字段,以节省磁盘空间,只需要设置 doc_values 为 false 就可以了,如下:

"session_id":{"type":"string","index":"not_analyzed","doc_values":false}

关闭doc_values后,该字段不能被排序,分组,聚合,但是能够节约磁盘空间

index:控制倒排索引,用于标识指定字段是否需要被索引。默认情况下是开启的,如果关闭了 index,则该字段的内容不会被 analyze 分词,也不会存入倒排索引,即意味着该字段无法被搜索。

关闭index后,该字段不能被检索,但是能够节约磁盘空间

上面相当的经典呀。

posted on 2022-07-19 18:58  luzhouxiaoshuai  阅读(112)  评论(0编辑  收藏  举报

导航