Elasticsearch 电商商品索引(Product Index)的完整方案

构建电商商品搜索引擎的Elasticsearch方案

在电商系统中,商品搜索是核心功能之一,而 Elasticsearch 正是构建高性能商品搜索引擎的理想选择。本文将为你详细设计一个 电商商品索引(Product Index)的完整方案,涵盖数据建模、字段设计、分片策略、搜索优化、聚合分析、生命周期管理等关键环节。


一、需求分析(电商商品搜索典型场景)

功能说明
全文检索支持按商品名称、品牌、描述等模糊搜索
结构化过滤按类目、品牌、价格区间、库存、属性(颜色/尺寸)筛选
排序综合排序、销量排序、价格排序、评分排序
聚合分析(Facets)展示左侧筛选面板(如“品牌”、“价格段”)
高亮显示搜索关键词高亮
相关性调优热门商品、新品优先
数据更新频繁商品信息、库存、价格实时变化
数据量大百万级甚至亿级商品

二、索引设计方案

1. 索引命名

采用 时间+业务 命名方式,便于滚动和管理:

product-catalog-2024-10

后续可通过 ILM + Rollover 实现自动滚动。


2. 索引别名(Aliases)

使用别名实现读写分离和无缝切换:

{
  "aliases": {
    "product-write": { "is_write_index": true },
    "product-read": {}
  }
}
  • 写入:POST /product-write/_doc
  • 搜索:GET /product-read/_search

3. 分片与副本设置

"settings": {
  "number_of_shards": 6,
  "number_of_replicas": 1,
  "refresh_interval": "30s"
}
设计依据:
  • 预估单索引数据量:500万商品 × 2KB ≈ 10GB
  • 每 shard 控制在 10~30GB,6 分片可支撑未来增长
  • 副本数 1:保证高可用和查询性能
  • refresh_interval: 30s:降低写入压力(商品更新非强实时)

若需近实时(如秒杀),可设为 1s


三、Mapping 字段设计

PUT /product-catalog-2024-10
{
  "settings": { ... },
  "mappings": {
    "dynamic": false,
    "properties": {
      "id": { "type": "keyword" },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "sub_title": { "type": "text", "analyzer": "ik_max_word" },
      "brand": { "type": "keyword" },
      "category_id": { "type": "keyword" },
      "category_path": { "type": "keyword" },  // "1001>2003>3005"
      "price": { "type": "scaled_float", "scaling_factor": 100 },  // 以分为单位存储
      "original_price": { "type": "scaled_float", "scaling_factor": 100 },
      "stock": { "type": "integer" },
      "status": { "type": "keyword" },  // on_sale, sold_out, deleted
      "sales_count": { "type": "long" },
      "rating": { "type": "float" },
      "tags": { "type": "keyword" },  // "新品", "爆款", "包邮"
      "images": {
        "type": "keyword",
        "index": false  // 不参与搜索,节省空间
      },
      "created_at": { "type": "date" },
      "updated_at": { "type": "date" },

      // 商品属性(如颜色、尺寸)—— nested 类型
      "attributes": {
        "type": "nested",
        "properties": {
          "name": { "type": "keyword" },   // "颜色"
          "value": { "type": "keyword" }   // "红色"
        }
      },

      // 商家信息
      "shop_id": { "type": "keyword" },
      "shop_name": { "type": "keyword" },

      // 地理位置(支持附近门店)
      "location": { "type": "geo_point" }
    }
  }
}

字段设计说明

字段类型说明
titletext + ik 分词支持中文全文检索
title.keywordkeyword用于排序、聚合(如按名称排序)
pricescaled_float避免 float 精度问题,scaling_factor=100 表示乘以 100 存储
category_pathkeyword支持按类目层级筛选
attributesnested支持“颜色=红色 AND 尺寸=XL”精确匹配
imageskeyword, index: false仅存储,不索引,节省空间
tagskeyword用于打标和筛选

四、搜索查询设计

1. 全文搜索 + 过滤 + 排序

GET /product-read/_search
{
  "query": {
    "bool": {
      "must": [
        { "match": { "title": "iPhone 手机" } }
      ],
      "filter": [
        { "term": { "brand": "Apple" } },
        { "range": { "price": { "gte": 500000, "lte": 1000000 } } },  // 5000~10000元
        { "nested": {
            "path": "attributes",
            "query": {
              "bool": {
                "must": [
                  { "match": { "attributes.name": "颜色" } },
                  { "match": { "attributes.value": "红色" } }
                ]
              }
            }
          }
        }
      ]
    }
  },
  "sort": [
    { "sales_count": { "order": "desc" } },
    { "rating": { "order": "desc" } },
    { "_score": { "order": "desc" } }
  ],
  "highlight": {
    "fields": {
      "title": {}
    }
  }
}

2. 聚合(Facets)用于筛选面板

"aggs": {
  "brands": {
    "terms": { "field": "brand", "size": 10 }
  },
  "price_ranges": {
    "range": {
      "field": "price",
      "ranges": [
        { "to": 100000 },    // < 1000元
        { "from": 100000, "to": 500000 },
        { "from": 500000 }
      ]
    }
  },
  "colors": {
    "nested": {
      "path": "attributes"
    },
    "aggs": {
      "color_values": {
        "filter": { "term": { "attributes.name": "颜色" } },
        "aggs": {
          "values": { "terms": { "field": "attributes.value" } }
        }
      }
    }
  }
}

五、性能优化建议

1. 写入优化

  • 使用 bulk API 批量导入商品。
  • 更新时使用 update API 局部更新(避免全量 reindex)。
  • 设置 refresh_interval: 30s 降低刷新开销。

2. 查询优化

  • 过滤条件优先使用 filter(不计算评分,可缓存)。
  • nested 查询性能较低,避免过度嵌套。
  • 使用 keyword 字段做聚合,避免 text 字段 fielddata

3. 相关性调优

使用 function_score 提升热门商品权重:

"function_score": {
  "query": { ... },
  "functions": [
    {
      "field_value_factor": {
        "field": "sales_count",
        "factor": 0.001,
        "modifier": "log1p"
      }
    },
    {
      "gauss": {
        "created_at": {
          "scale": "7d"
        }
      }
    }
  ],
  "boost_mode": "multiply"
}

六、索引生命周期管理(ILM)

1. 策略设计

PUT /_ilm/policy/product-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": { "max_age": "30d", "max_size": "50gb" }
        }
      },
      "warm": {
        "min_age": "30d",
        "actions": {
          "forcemerge": { "max_num_segments": 1 },
          "shrink": { "number_of_shards": 3 }
        }
      },
      "delete": {
        "min_age": "365d",
        "actions": { "delete": {} }
      }
    }
  }
}

2. 应用到模板

PUT /_index_template/product-template
{
  "index_patterns": ["product-catalog-*"],
  "template": {
    "settings": {
      "number_of_shards": 6,
      "number_of_replicas": 1,
      "index.lifecycle.name": "product-policy",
      "index.lifecycle.rollover_alias": "product-write"
    },
    "mappings": { ... }
  }
}

首次创建 product-catalog-000001 并指向 product-write 别名。


七、数据同步方案

1. 同步方式

  • CDC(Change Data Capture):监听 MySQL binlog(通过 Canal、Debezium)。
  • MQ 消息:商品服务发送 product.updated 事件到 Kafka。
  • 定时 Job:每日全量同步(兜底)。

2. 更新策略

  • 增量更新使用 POST /product-write/_update
  • 删除使用 POST /product-write/_delete_by_query(按 ID)。

八、高可用与监控

  • 集群部署:至少 3 个节点,启用分片自动均衡。
  • 监控指标:
    • 索引速率(indexing.rate
    • 查询延迟(search.latency
    • JVM 内存、GC
    • 分片状态(unassigned_shards

九、总结:电商商品索引架构图

+------------------+     +---------------------+
|  MySQL / Kafka   | --> | Logstash / Flink    |
+------------------+     +----------+----------+
                                    |
                                    v
                     +--------------------------+
                     | Elasticsearch Cluster    |
                     |                          |
                     | Index: product-catalog-* |
                     | Aliases:                 |
                     |   - product-write        |
                     |   - product-read         |
                     +------------+-------------+
                                  |
                                  v
                     +--------------------------+
                     |        Kibana / App      |
                     |  Search, Filter, Facets  |
                     +--------------------------+

十、扩展建议

  • 支持多语言:使用 multi-field 存储英文标题。
  • 商品推荐:结合 more_like_this 查询。
  • 拼音搜索:使用 pinyin analyzer 支持“iphone”搜“苹果”。
  • 向量搜索:未来可接入 dense_vector 实现“以图搜商品”。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值