(只有上架的商品存储到Elasticsearch中才能被检索)

分析-存储商品的什么信息到 es 中

1. 需要保存 sku 信息

  • 当搜索商品名时,查询的是 sku 的标题 sku_title;
  • 可能通过 sku 的标题、销量、价格区间检索

    2. 需要保存品牌、分类等信息

  • 点击分类,检索分类下的所有信息

  • 点击品牌,检索品牌下的商品信息

    3. 需要保存 spu 信息

  • 选择规格,检索共有这些规格的商品

    分析-怎么设计存储结构来保存数据

    1. 方案1-空间换时间

    1. {
    2. skuId:1
    3. spuId:11
    4. skyTitile:华为xx
    5. price:999
    6. saleCount:99
    7. attrs:[
    8. {尺寸:5存},
    9. {CPU:高通945},
    10. {分辨率:全高清}
    11. ]
    12. }
    13. # 缺点:会产生冗余字段,对于相同类型的商品,attrs 属性字段会重复,空间占用大
    14. # 好处:方便检索

    2. 方案2-时间换空间

    1. sku索引
    2. {
    3. skuId:1
    4. spuId:11
    5. }
    6. attr索引
    7. {
    8. spuId:11
    9. attrs:[
    10. {尺寸:5寸},
    11. {CPU:高通945},
    12. {分辨率:全高清}
    13. ]
    14. }
    15. # 缺点:选择公共属性attr时,会检索当前属性的所有商品分类,然后再查询当前商品分类的所有可能属性;
    16. # 导致耗时长。
    17. # 好处:空间利用率高

    3. 最终方案-存储结构

    完整结构:

    1. PUT product
    2. {
    3. "mappings": {
    4. "properties": {
    5. "skuId": { "type": "long" },
    6. "spuId": { "type": "keyword" },
    7. "skuTitle": {
    8. "type": "text",
    9. "analyzer": "ik_smart"
    10. },
    11. "skuPrice": { "type": "keyword" },
    12. "skuImg": {
    13. "type": "keyword",
    14. "index": false,
    15. "doc_values": false
    16. },
    17. "saleCount":{ "type":"long" },
    18. "hasStock": { "type": "boolean" },
    19. "hotScore": { "type": "long" },
    20. "brandId": { "type": "long" },
    21. "catalogId": { "type": "long" },
    22. "brandName": {
    23. "type": "keyword",
    24. "index": false,
    25. "doc_values": false
    26. },
    27. "brandImg":{
    28. "type": "keyword",
    29. "index": false,
    30. "doc_values": false
    31. },
    32. "catalogName": {
    33. "type": "keyword",
    34. "index": false,
    35. "doc_values": false
    36. },
    37. "attrs": {
    38. "type": "nested",
    39. "properties": {
    40. "attrId": {"type": "long" },
    41. "attrName": {
    42. "type": "keyword",
    43. "index": false,
    44. "doc_values": false
    45. },
    46. "attrValue": { "type": "keyword" }
    47. }
    48. }
    49. }
    50. }
    51. }

    mapping结构字段说明:

    1. "mappings": {
    2. "properties": {
    3. "skuId": { "type": "long" },
    4. "spuId": { "type": "keyword" }, # 精确检索,不分词
    5. "skuTitle": {
    6. "type": "text", # 全文检索
    7. "analyzer": "ik_smart" # 分词器
    8. },
    9. "skuPrice": { "type": "keyword" },
    10. "skuImg": {
    11. "type": "keyword",
    12. "index": false, # false 不可被检索
    13. "doc_values": false # false 不可被聚合
    14. },
    15. "saleCount":{ "type":"long" }, # 商品销量
    16. "hasStock": { "type": "boolean" }, # 商品是否有库存
    17. "hotScore": { "type": "long" }, # 商品热度评分
    18. "brandId": { "type": "long" }, # 品牌id
    19. "catalogId": { "type": "long" }, # 分类id
    20. "brandName": { # 品牌名,只用来查看,不用来检索和聚合
    21. "type": "keyword",
    22. "index": false,
    23. "doc_values": false
    24. },
    25. "brandImg":{ # 品牌图片,只用来查看,不用来检索和聚合
    26. "type": "keyword",
    27. "index": false,
    28. "doc_values": false
    29. },
    30. "catalogName": { # 分类名,只用来查看,不用来检索和聚合
    31. "type": "keyword",
    32. "index": false,
    33. "doc_values": false
    34. },
    35. "attrs": { # 属性对象
    36. "type": "nested", # 嵌入式,内部属性
    37. "properties": {
    38. "attrId": {"type": "long" },
    39. "attrName": { # 属性名
    40. "type": "keyword",
    41. "index": false,
    42. "doc_values": false
    43. },
    44. "attrValue": { "type": "keyword" } # 属性值
    45. }
    46. }
    47. }
    48. }

    4. 关于 nested 类型

    官网:Nested field type

  • Object 数据类型的数组会被扁平化处理为一个简单的键与值的列表,即对象的相同属性会放到同一个数组中,在检索时会出现错误。参考官网:How arrays of objects are flattened

  • 对于 Object 类型的数组,要使用 nested 字段类型。参考官网:Using nested fields for arrays of objects