搜索 + 比价 | 多平台数据聚合 | 混合检索


一、系统架构总览

数据存储层

Elasticsearch
搜索+向量索引

MySQL
业务数据/元数据

Redis
缓存/分布式锁/限流

数据处理层

数据采集
Scheduler

数据清洗
ETL管道

向量化
Embedding

索引构建
ES写入

服务层

搜索服务

比价服务

商品服务

前端应用层

Web搜索界面 / API接口 / 数据可视化面板


二、技术栈选型

层级 技术组件 说明
后端框架 Spring Boot 3.x Java主服务
搜索引擎 阿里云 Elasticsearch 8.x 倒排索引 + 向量索引 + 混合检索
关系型数据库 MySQL 8.0 业务数据、任务调度、用户数据
缓存 Redis 7.x 热点数据缓存、分布式锁、限流
向量模型 Qwen text-embedding-v3 商品文本向量化(1024维)
稀疏向量模型 SPLADE 关键字扩展与词元权重
爬虫框架 Selenium WebDriver (Java) 动态页面采集
任务调度 XXL-JOB 定时采集任务管理
容器化 Docker + Docker Compose 服务部署

三、数据采集模块

3.1 数据源分类

数据源类型 平台 接入方式 优先级
官方开放平台 京东 Open API (签名认证) P0
官方开放平台 拼多多 Open API (签名认证) P0
官方开放平台 1688 Open API (TOP协议) P0
官方开放平台 抖音电商 Open API (OAuth2.0) P1
第三方聚合 万邦开放平台 REST API P1
第三方聚合 聚美数仓 REST API P1
自研爬虫 各平台 Selenium WebDriver P2

3.2 采集架构设计

采集调度中心 (XXL-JOB)

京东采集 Worker

拼多多 Worker

1688采集 Worker

抖音采集 Worker

同步处理管道

1. 数据采集

2. 数据清洗

3. 向量化

4. 写入 ES

5. 更新 MySQL

3.3 各平台API接入说明

3.3.1 京东开放平台
项目 说明
认证方式 AppKey + AppSecret
签名算法 MD5签名(secret + 排序参数 + secret)
基础URL https://api.jd.com/routerjson
核心接口 jingdong.ware.search(商品搜索)
限流策略 单应用QPS限制,需控制请求频率
数据返回 JSON格式,包含商品ID、标题、价格、图片等

接入要点:

  • 请求参数按字母排序后拼接签名
  • 时间戳使用毫秒级
  • 需处理API限流,实现重试机制
  • 商品数据需定时增量更新
3.3.2 拼多多开放平台
项目 说明
认证方式 ClientID + ClientSecret
签名算法 MD5签名(secret + 排序参数 + secret)
基础URL https://gw-api.pinduoduo.com/api/router
核心接口 pdd.ddk.goods.search(多多进宝商品搜索)
请求方式 POST
数据返回 JSON格式,包含商品详情、优惠券信息等

接入要点:

  • 时间戳使用秒级
  • POST请求,参数放在body中
  • 多多进宝接口可获取推广佣金信息
  • 部分接口需要用户授权token
3.3.3 1688开放平台
项目 说明
认证方式 AppKey + AppSecret
签名算法 MD5签名(排序参数拼接)
基础URL https://gw.open.1688.com/openapi/param2/1
核心接口 alibaba.offer.search(商品搜索)
协议 TOP协议
数据返回 JSON格式,包含批发价格、起订量等

接入要点:

  • URL路径包含appKey和接口名称
  • 批发商品有起订量、阶梯价格等特殊字段
  • 部分数据需要企业账号权限
3.3.4 抖音电商开放平台
项目 说明
认证方式 OAuth2.0
Token获取 AppID + AppSecret 换取 AccessToken
基础URL https://openapi-fxg.jinritemai.com
核心接口 商品搜索、商品详情
Token有效期 通常24小时,需定时刷新
数据返回 JSON格式,包含商品、直播等信息

接入要点:

  • AccessToken需缓存,提前5分钟刷新
  • 部分接口需要用户授权
  • 直播商品数据实时更新频率高

3.4 自研爬虫模块

技术选型: Selenium WebDriver (Java)

爬虫架构:

爬虫调度器

BaseCrawler 抽象基类
createDriver() 创建浏览器驱动
crawl() 执行爬取流程
search() 搜索商品(抽象)
parseProduct() 解析商品(抽象)

TBCrawler
(淘宝/天猫)

其他爬虫
(扩展)

反爬策略:

  • 无头浏览器模式运行
  • 移除 webdriver 特征标识
  • 设置合理的请求间隔(2-5秒)
  • 使用代理IP池轮换
  • Cookie池管理

数据采集流程:

  1. 创建WebDriver实例(配置反爬参数)
  2. 导航到搜索页面
  3. 等待页面加载完成(显式等待)
  4. 解析商品列表元素
  5. 提取商品标题、价格、销量等信息
  6. 翻页继续采集
  7. 关闭浏览器,释放资源

四、数据清洗与归一化模块

4.1 数据清洗流程总览

原始数据
(Raw JSON)

格式校验 & 过滤
结构校验 / 空值检查
异常拦截 / 类型转换

字段提取 & 转换
平台映射 / 字段转换

数据标准化 & 归一化
价格/文本/图片
时间/类目归一化

去重过滤 & 合并
唯一标识 / 模糊匹配
版本控制

质量评分 & 入库
质量打分 / 分级入库
异常标记

多平台原始JSON

校验规则

字段映射表

标准化规则

去重算法

质量等级 A/B/C/D

4.2 详细清洗步骤

4.2.1 第一步:格式校验与过滤

目标: 拦截无效数据,确保进入后续流程的数据结构正确

校验项 规则 处理方式
JSON格式校验 必须是合法JSON 解析失败直接丢弃,记录错误日志
必填字段检查 product_id、title、price 不能为空 缺失则丢弃,记录缺失字段
数据类型校验 价格必须为数值型、销量必须为整型 类型错误尝试转换,转换失败则丢弃
数据范围校验 价格 > 0 且 < 999999、销量 >= 0 超出范围标记为异常,进入人工审核队列
平台标识校验 必须是预定义平台枚举值 未知平台直接丢弃

异常处理策略:

  • 轻微异常(可修复):尝试自动修复后继续流程
  • 严重异常(不可修复):丢弃数据,写入异常日志表
  • 可疑异常(需人工判断):写入待审核队列
4.2.2 第二步:字段提取与转换

目标: 将各平台异构数据映射为统一数据模型

平台字段映射表:

统一字段 京东字段 拼多多字段 1688字段 抖音字段
product_id wareId goodsId offerId productId
title wareName goodsName subject title
price jdPrice minGroupPrice priceRange.min price
original_price marketPrice marketPrice originalPrice originPrice
sales_count commentCount salesTip amountOnSale -
review_count commentCount - - -
rating goodRate - - rate
brand brandName brandName brand brandName
category categoryId categoryId category categoryId
main_image imageInfo goodsThumbnailUrl imageUrls[0] mainImg
images imageInfoList goodsGalleryUrls imageUrls detailImgList
shop_name shopName mallName companyName shopName
shop_id shopId mallId memberId shopId
product_url wareUrl goodsUrl offerDetailUrl productUrl

类型转换规则:

源类型 目标类型 转换规则
字符串价格 “99.00” Float 99.00 去除货币符号,解析为浮点数
价格区间 “50-100” Float 50.00 取区间最小值
销量字符串 “1万+” Integer 10000 解析中文数字,转换为整数
评分字符串 “4.8分” Float 4.8 提取数值部分
时间戳(毫秒) DateTime 转换为标准日期时间格式
HTML富文本 纯文本 去除HTML标签,保留文字内容
4.2.3 第三步:数据标准化与归一化

(1)价格标准化

标准化项 规则 示例
货币统一 所有价格转换为人民币(元) $14.99 → ¥109.00(按汇率)
精度统一 保留两位小数 99.999 → 100.00
促销价处理 优先取实际成交价,而非标价 原价199,促销价99 → 取99
券后价处理 记录券后价和原价两个字段 price=89, original_price=119
阶梯价格 取最低起订量对应的价格 1件100元,10件90元 → 取100
异常价格过滤 价格<=0或>999999标记异常 -1、0、9999999 → 标记异常
价格单位转换 部分平台以"分"为单位 9900分 → 99.00元

(2)文本清洗

清洗项 规则 示例
HTML标签去除 移除所有 <tag> 标签 <b>手机</b>手机
特殊字符去除 移除不可见字符、emoji 手机📱手机
多余空格合并 连续空格合并为单个空格 苹果 手机苹果手机
广告词过滤 移除营销类词汇 【包邮】正品手机手机
全角转半角 全角数字/字母转半角 123123
大小写统一 品牌名保留原样,其他转小写 APPLEapple

广告词黑名单:

类别 词汇
物流类 包邮、顺丰、包邮到家、全国包邮
品质类 正品、原装、原厂、真品、正品保障
促销类 特价、限时、抢购、秒杀、清仓、打折
热度类 爆款、热卖、热销、畅销、网红
新品类 新品、新款、上新、最新
官方类 官方、旗舰店、官网、授权
符号类 【】、[]、★、◆、●、▲

(3)图片URL标准化

处理项 规则
URL去重 同一商品多张图片去重
协议统一 http 升级为 https
尺寸参数去除 去除URL中的尺寸参数,获取原图
无效链接过滤 检测404/空图片,标记无效

(4)类目归一化

处理项 规则
平台类目映射 各平台类目映射到统一类目树
多级类目扁平化 保留最多3级类目
未知类目处理 映射到"其他"类目

(5)时间标准化

处理项 规则
时区统一 所有时间转换为北京时间(UTC+8)
格式统一 yyyy-MM-dd HH:mm:ss
时间戳转换 毫秒/秒级时间戳转换为可读格式
4.2.4 第四步:去重与合并

(1)精确去重

去重维度 规则 说明
平台内去重 platform + product_id 唯一 同一平台同一商品ID视为重复
跨平台去重 多维度相似度 >= 0.85 不同平台的同款商品,详见10.3节AI去重算法

(2)模糊去重算法

相似度计算 = 0.40 × 标题语义相似度 
           + 0.25 × 品牌匹配度 
           + 0.20 × 类目匹配度
           + 0.15 × 价格接近度

判定规则:
- 相似度 >= 0.85:视为同款商品,合并数据
- 0.70 <= 相似度 < 0.85:疑似同款,进入人工审核
- 相似度 < 0.70:视为不同商品

(3)数据合并策略

当识别为同款商品时:

字段 合并策略
价格 保留各平台价格,用于比价
标题 选择信息最完整的版本
图片 合并所有平台图片,去重后保留
销量 各平台销量独立保留
描述 合并多平台描述,去重
更新时间 取最新更新时间

(4)版本控制

策略 说明
数据版本 每次更新生成新版本号
历史保留 保留最近10个版本的价格历史
变更追踪 记录价格变动、标题变动等
4.2.5 第五步:质量评分与分级

质量评分维度:

评分项 权重 评分标准
字段完整度 30% 必填字段齐全得满分,缺失扣分
数据准确性 25% 通过校验规则的数量占比
图片质量 20% 有主图且有效得满分
描述完整度 15% 有详细描述得满分
时效性 10% 数据更新时间距今越近得分越高

质量分级:

等级 分数 说明 处理方式
A级(优质) >= 90 字段完整、数据准确 直接入库,优先展示
B级(良好) 70-89 基本完整,少量缺失 直接入库,正常展示
C级(一般) 50-69 部分字段缺失 入库但降低搜索权重
D级(较差) < 50 大量字段缺失 标记异常,人工审核

4.3 统一商品数据模型

字段类别 字段名 类型 说明
基础信息 product_id String 平台商品唯一ID
platform Enum 来源平台(jd/pdd/1688/douyin)
title String 商品标题
subtitle String 副标题/卖点
description String 商品描述
价格信息 price Float 当前售价(元)
original_price Float 原价/划线价
currency String 货币单位(默认CNY)
销售信息 sales_count Integer 销量
review_count Integer 评论数
rating Float 评分(1-5)
分类信息 category String 商品类目
brand String 品牌
tags List 标签列表
图片信息 main_image String 主图URL
images List 图片URL列表
商家信息 shop_name String 店铺名称
shop_id String 店铺ID
shop_rating Float 店铺评分
链接信息 product_url String 商品详情页URL
affiliate_url String 推广链接
时间信息 crawl_time DateTime 爬取时间
updated_at DateTime 更新时间
质量信息 quality_score Float 质量评分(0-100)
quality_level Enum 质量等级(A/B/C/D)
向量信息 title_embedding Float[] 标题向量(1024维)
desc_embedding Float[] 描述向量(1024维)

4.4 异常数据处理

异常类型与处理:

异常类型 示例 处理方式
解析异常 JSON格式错误 丢弃,记录错误日志
字段缺失 缺少商品ID 尝试从URL提取,失败则丢弃
类型错误 价格为字符串"免费" 转换为0或标记异常
范围异常 价格99999999 标记异常,人工审核
链接失效 图片404 标记无效,使用备用图
重复数据 同一商品多次采集 更新时间戳,保留最新版本

异常数据流转:

异常数据

异常分类

自动修复

修复成功?

正常流程

修复失败

人工审核

4.5 清洗流程性能优化

优化点 方案
批量处理 每批100-500条数据并行清洗
同步管道 采集完直接清洗入库,简化架构
缓存复用 类目映射表、广告词黑名单加载到内存
并行计算 多平台数据并行清洗
失败重试 单次失败最多重试3次,间隔递增
监控告警 清洗失败率超过阈值触发告警

五、数据存储与索引构建

5.1 Elasticsearch 索引设计

5.1.1 索引配置
配置项 说明
分片数 3 根据数据量调整
副本数 1 保证高可用
中文分词 ik_smart / ik_max_word 标题用max_word,搜索用smart
5.1.2 字段映射
字段 类型 分词器 说明
product_id keyword - 精确匹配
platform keyword - 精确匹配/过滤
title text ik_max_word 全文检索
title.keyword keyword - 精确匹配
title.dense_vector dense_vector - 稠密向量(1024维)
title.sparse_vector sparse_vector - 稀疏向量
description text ik_max_word 全文检索
price float - 数值范围查询
sales_count integer - 数值排序
category keyword - 分类过滤
brand keyword - 品牌过滤
tags keyword - 标签过滤
crawl_time date - 时间范围查询
desc.dense_vector dense_vector - 描述稠密向量(1024维)

5.2 向量化服务

向量模型选型:

模型 维度 特点 适用场景
Qwen text-embedding-v3 1024 中文语义理解强、支持多语言 商品标题/描述语义检索

向量化流程:

商品入库时,对同一份商品数据同步执行向量化:

文本预处理

【输入】商品数据
标题 / 描述 / 品牌 / 类目

标题清洗后文本
标题+品牌+类目

原始标题文本

描述清洗后文本

【Qwen】标题稠密向量
1024维

【SPLADE】标题稀疏向量

【Qwen】描述稠密向量
1024维

写入 ES
title.dense_vector

写入 ES
title.sparse_vector

写入 ES
desc.dense_vector

向量化完成

关键说明:

  • 标题向量化:Qwen(清洗后标题+品牌+类目)+ SPLADE(原始标题文本)
  • 描述向量化:Qwen(清洗后描述文本),仅生成稠密向量
  • 所有向量化同步执行,互不依赖
  • 最终同时写入ES对应字段

批量处理策略:

  • 批量向量化(每批100条)
  • 同步处理,采集完直接清洗入库
  • 失败重试机制
  • GPU加速(可选)

5.3 索引写入策略

写入流程:

  1. 采集Worker调用平台API获取原始数据
  2. 同步调用数据清洗服务,执行格式校验、字段映射、标准化
  3. 调用向量化服务生成标题稠密向量、标题稀疏向量、描述稠密向量
  4. 批量写入Elasticsearch
  5. 更新MySQL元数据(采集状态、时间等)

性能优化:

  • 使用ES bulk API批量写入
  • 每批100-500条记录
  • 写入时关闭refresh_interval,完成后恢复
  • 冷热数据分离(近期数据SSD,历史数据HDD)

六、数据检索服务

6.1 混合检索架构

用户查询: iPhone 15 手机壳

关键字检索 (BM25)

稠密向量语义检索
(Qwen 1024维)

稀疏向量词元检索
(SPLADE)

RRF 融合排序
Reciprocal Rank Fusion

最终结果排序
(价格/销量/品牌等)

6.2 三路检索说明

检索路 技术 权重 优势 劣势
BM25关键字 倒排索引 + ik分词 0.3 精确匹配、可解释性强 无法理解语义
稠密向量语义 向量相似度(余弦) 0.4 语义理解、同义词匹配 计算开销大
稀疏向量词元 SPLADE词元权重 0.3 兼顾精确与语义 模型依赖

6.3 RRF融合排序

RRF(Reciprocal Rank Fusion)算法:

  • 公式:RRF(d) = Σ 1 / (k + rank(d))
  • 参数 k 通常设为 60
  • 将三路检索结果按排名倒数加权求和
  • 最终按RRF得分降序排列

优势:

  • 无需训练权重,简单有效
  • 自动平衡不同检索路的结果
  • 对排名靠前的结果给予更高权重

6.4 过滤与排序

支持的过滤条件:

  • 平台过滤(京东/拼多多/1688/抖音)
  • 价格区间过滤
  • 品牌过滤
  • 类目过滤
  • 标签过滤
  • 时间范围过滤

支持的排序方式:

  • 相关度排序(默认,RRF得分)
  • 价格升序/降序
  • 销量排序
  • 评分排序
  • 上架时间排序

6.5 比价服务

比价逻辑:

  1. 根据搜索词检索商品
  2. 按平台分组
  3. 每个平台取最低价商品
  4. 按价格升序排列各平台结果
  5. 返回最优购买建议

比价结果包含:

  • 各平台最低价
  • 对应商品信息
  • 平台商品数量
  • 价格差异百分比
  • 最优购买推荐

七、定时采集任务调度

7.1 任务调度架构

调度中心: XXL-JOB

XXL-JOB 调度中心

任务管理界面
- 任务配置/启停
- 执行日志查看
- 告警配置

执行器A
(采集服务)

执行器B
(清洗服务)

7.2 采集任务配置

任务名称 执行频率 Cron表达式 说明
全量商品同步 每日1次 0 0 2 * * ? 每天凌晨2点全量更新
增量商品同步 每4小时 0 0 */4 * * ? 价格变动、新增商品
热门商品监控 每小时 0 0 * * * ? 热门商品价格追踪
向量索引重建 每周1次 0 0 3 ? * SUN 重新生成向量
过期数据清理 每日1次 0 30 3 * * ? 清理过期/无效数据

7.3 任务执行流程

全量同步流程:

  1. 触发全量同步任务
  2. 依次调用各平台API获取商品列表
  3. 同步执行数据清洗与归一化
  4. 调用向量化服务生成标题/描述向量
  5. 批量写入Elasticsearch
  6. 更新MySQL任务执行状态
  7. 发送执行报告

增量同步流程:

  1. 获取上次同步时间戳
  2. 查询各平台增量数据
  3. 仅处理新增和变更商品
  4. 更新ES索引
  5. 记录同步位点

八、API接口设计

8.1 RESTful API列表

接口路径 方法 说明 权限
/api/v1/products/search GET 商品混合检索 公开
/api/v1/products/compare GET 多平台比价 公开
/api/v1/products/{platform}/{id} GET 商品详情 公开
/api/v1/products/hot GET 热门商品 公开
/api/v1/categories GET 类目列表 公开
/api/v1/price/history/{platform}/{id} GET 价格历史 公开

8.2 搜索接口说明

请求参数:

参数 类型 必填 说明
query String 搜索关键词
platforms String 平台过滤,逗号分隔
min_price Float 最低价格
max_price Float 最高价格
brand String 品牌过滤
category String 类目过滤
sort_by String 排序方式
page Integer 页码,默认1
page_size Integer 每页数量,默认20

响应结构:

字段 类型 说明
total Integer 总结果数
page Integer 当前页码
page_size Integer 每页数量
results Array 商品列表

商品对象字段:

字段 类型 说明
product_id String 商品ID
platform String 来源平台
title String 商品标题
price Float 价格
original_price Float 原价
sales_count Integer 销量
rating Float 评分
brand String 品牌
main_image String 主图
product_url String 商品链接
shop_name String 店铺名称
score Float 相关度得分

8.3 比价接口说明

请求参数:

参数 类型 必填 说明
query String 商品搜索词
platforms String 指定平台

响应结构:

字段 类型 说明
query String 搜索词
comparison Array 各平台比价结果
best_deal Object 最优购买推荐

九、部署架构

9.1 服务组件

服务 端口 说明
Elasticsearch 9200 搜索引擎
MySQL 3306 关系型数据库
Redis 6379 缓存服务
XXL-JOB Admin 8081 任务调度中心
后端API服务 8080 主服务
数据采集服务 - 后台Worker
Nginx 80/443 反向代理

9.3 资源配置建议

组件 CPU 内存 磁盘
Elasticsearch 4核+ 8GB+ SSD 100GB+
MySQL 2核+ 4GB+ SSD 50GB+
Redis 1核 2GB -
后端服务 2核+ 4GB+ -
采集服务 2核+ 4GB+ -

十、AI应用与核心算法

10.1 AI在系统中的角色

AI能力 模型/技术 用途
稠密向量嵌入 Qwen text-embedding-v3 商品标题/描述语义理解
稀疏向量生成 SPLADE 关键字扩展与词元权重
混合检索融合 RRF算法 多路召回结果排序
语义去重 向量余弦相似度 跨平台同款商品识别
查询理解 Query改写/纠错 搜索词优化
智能推荐 协同过滤+向量检索 相似商品推荐
价格预测 时序模型 价格趋势预测

10.2 混合检索详细实现

10.2.1 检索流程总览

用户查询: iPhone 15 手机壳

Query处理
(分词/纠错)

Query向量化
(Qwen模型)

BM25检索
(倒排索引)

稠密向量检索
(HNSW索引)

稀疏向量检索
(词元权重)

RRF 融合排序
score = Σ 1/(k + rank_i(d))

业务规则过滤与重排
(价格区间/品牌/平台/销量排序)

10.2.2 第一路:BM25关键字检索

实现原理:

  • 基于ES倒排索引,使用ik分词器对中文分词
  • BM25算法根据词频(TF)和逆文档频率(IDF)计算相关性

分词策略:

场景 分词器 说明
索引时 ik_max_word 最大细粒度分词,提高召回率
搜索时 ik_smart 粗粒度分词,减少噪声

同义词扩展:

  • 维护同义词词典:手机→移动电话、壳→保护套、iPhone→苹果手机
  • 搜索时自动扩展同义词,提升召回

ES查询示例逻辑:

查询: "iPhone 15 手机壳"
分词: ["iPhone", "15", "手机壳", "手机", "壳"]
同义词扩展: ["iPhone", "苹果手机", "15", "手机壳", "保护套", "手机", "壳"]
BM25评分: 基于词频和逆文档频率计算相关性得分

优势与局限:

  • 优势:精确匹配、可解释性强、速度快
  • 局限:无法理解语义,“苹果手机壳"搜不到"iPhone保护套”
10.2.3 第二路:稠密向量语义检索

实现原理:

  • 使用Qwen text-embedding-v3模型将查询和商品文本转为1024维向量
  • 通过向量余弦相似度计算语义相关性
  • ES使用HNSW近似最近邻索引加速检索

向量化流程:

用户搜索时

查询: 苹果手机保护套

Qwen Encoder

[0.11, -0.33, 0.55, ...]
(查询向量)

ES HNSW向量检索
返回Top-K相似商品

商品入库时

商品标题
苹果iPhone 15 Pro Max手机壳

Qwen Encoder

[0.12, -0.34, 0.56, ...]
(1024维稠密向量)

写入ES
title.dense_vector

相似度计算:

余弦相似度 = (A·B) / (||A|| × ||B||)

示例:
查询向量: "苹果手机保护套" → [0.11, -0.33, 0.55, ...]
商品向量: "iPhone 15 Pro Max手机壳" → [0.12, -0.34, 0.56, ...]

余弦相似度 = 0.92 (高度相似)
→ 即使字面不同,语义上匹配

HNSW索引参数:

参数 说明
m 16 每个节点的最大连接数
ef_construction 100 构建索引时的搜索深度
ef_search 50 查询时的搜索深度,越大越准越慢

优势与局限:

  • 优势:语义理解强,能匹配字面不同但含义相同的商品
  • 局限:计算开销大,对精确匹配不如BM25
10.2.4 第三路:稀疏向量词元检索(SPLADE)

实现原理:

  • SPLADE模型将文本转为稀疏向量,每个维度对应词汇表中的一个词
  • 向量值表示该词对文本的重要性权重
  • 兼具BM25的精确性和向量的语义扩展能力

稀疏向量示例:

文本: "iPhone 15 手机壳"

SPLADE稀疏向量:
{
  "iphone": 0.85,
  "15": 0.72,
  "手机": 0.68,
  "手机壳": 0.91,
  "保护套": 0.45,    // 语义扩展
  "苹果": 0.38,      // 语义扩展
  "配件": 0.25,      // 语义扩展
  ...
}

与BM25的区别:

  • BM25:基于统计,词权重由TF-IDF决定
  • SPLADE:基于神经网络,自动学习词的重要性和扩展相关词

优势与局限:

  • 优势:兼顾精确匹配和语义扩展,可解释性比稠密向量好
  • 局限:依赖SPLADE模型质量,词汇表外词处理有限
10.2.5 RRF融合排序详解

RRF算法公式:

RRF_score(d) = Σ 1 / (k + rank_i(d))

其中:
- d: 文档(商品)
- k: 常数,通常设为60
- rank_i(d): 文档d在第i路检索中的排名

融合示例:

商品 BM25排名 稠密向量排名 稀疏向量排名 RRF得分
商品A 1 3 2 1/61 + 1/63 + 1/62 = 0.0487
商品B 2 1 5 1/62 + 1/61 + 1/65 = 0.0481
商品C 5 2 1 1/65 + 1/62 + 1/61 = 0.0478
商品D 3 8 4 1/63 + 1/68 + 1/64 = 0.0463

加权RRF(可选):

RRF_score(d) = Σ weight_i / (k + rank_i(d))

默认权重:
- BM25: 0.3
- 稠密向量: 0.4
- 稀疏向量: 0.3

为什么k=60?

  • k值影响排名靠前结果的权重差异
  • k=60是信息检索领域的经验值
  • k越小,排名靠前的结果权重差异越大
  • k越大,各排名结果权重差异越平滑
10.2.6 检索性能优化
优化点 方案 效果
查询缓存 Redis缓存热门搜索Query结果 命中率>60%的查询直接返回
向量索引 HNSW近似最近邻 检索速度提升10-100倍
分页优化 search_after替代from/size 深分页性能提升
字段裁剪 只返回必要字段 网络传输减少50%
并发检索 三路检索并行执行 延迟降低至最慢的一路
预热机制 定时更新热门商品向量 冷启动延迟降低

10.3 AI商品去重详细实现

10.3.1 去重场景
场景 说明 示例
平台内去重 同一平台重复采集 京东同一商品被多次采集
跨平台同款 不同平台的同款商品 京东/拼多多都有iPhone 15
SKU变体 同一商品不同规格 iPhone 15 128G vs 256G
套装组合 商品+配件组合 手机壳+钢化膜套装
10.3.2 精确去重

规则:

唯一标识 = platform + product_id

去重逻辑:
1. 新数据到来时,检查 (platform, product_id) 是否已存在
2. 已存在 → 比较更新时间
   - 新数据更新 → 覆盖旧数据,记录变更历史
   - 旧数据更新 → 丢弃新数据
3. 不存在 → 直接入库
10.3.3 跨平台模糊去重(AI核心)

多维度相似度计算:

综合相似度 = w1 × 标题语义相似度 
           + w2 × 品牌匹配度 
           + w3 × 类目匹配度
           + w4 × 价格接近度

权重配置:
w1 = 0.40 (标题语义)
w2 = 0.25 (品牌匹配)
w3 = 0.20 (类目匹配)
w4 = 0.15 (价格接近)

(1)标题语义相似度

方法:向量余弦相似度

步骤:
1. 将两个商品标题分别转为1024维向量
2. 计算余弦相似度

示例:
标题A: "Apple iPhone 15 Pro Max 256GB 原色钛金属"
标题B: "苹果15ProMax 256G 原色钛金属手机"

向量A: [0.12, -0.34, 0.56, ...]
向量B: [0.11, -0.33, 0.55, ...]

余弦相似度 = 0.94 (高度相似)

(2)品牌匹配度

匹配情况 得分 示例
完全相同 1.0 Apple vs Apple
别名匹配 0.9 Apple vs 苹果
包含关系 0.7 Apple vs Apple授权
不同 0.0 Apple vs Samsung

品牌别名映射表:

标准品牌 别名
Apple 苹果、iPhone、iPad
Huawei 华为
Xiaomi 小米、MI
OPPO OPPO、欧珀
vivo vivo、维沃
Samsung 三星、Galaxy

(3)类目匹配度

方法:类目树路径匹配

示例:
类目A: 手机通讯 > 手机 > 智能手机
类目B: 数码 > 手机 > 智能手机

匹配逻辑:
1. 计算类目路径的Jaccard相似度
2. 检查末级类目是否相同

Jaccard = |A∩B| / |A∪B| = 2/4 = 0.5
末级相同 → 额外加分

最终类目匹配度 = 0.7

(4)价格接近度

方法:基于价格比率计算

公式:
price_ratio = min(priceA, priceB) / max(priceA, priceB)
price_score = price_ratio  (范围0-1)

示例:
价格A: 8999元
价格B: 8799元

price_ratio = 8799 / 8999 = 0.978
price_score = 0.978 (价格非常接近)

阈值:
- price_score >= 0.8: 价格接近
- 0.5 <= price_score < 0.8: 价格有一定差异
- price_score < 0.5: 价格差异大,可能不是同款
10.3.4 去重判定与处理

判定阈值:

综合相似度 判定结果 处理方式
>= 0.85 同款商品 自动合并,保留各平台价格用于比价
0.70 - 0.85 疑似同款 标记待审核,人工确认
< 0.70 不同商品 独立保留

同款商品合并策略:

字段 合并策略 说明
product_group_id 生成统一ID 同款商品共享一个group_id
各平台价格 全部保留 用于比价展示
标题 选信息最完整版本 或拼接各平台标题
图片 合并去重 保留所有平台有效图片
描述 合并去重 补充各平台描述信息
销量 各平台独立 不合并,分别展示
更新时间 取最新 记录最后更新时间
10.3.5 去重性能优化
优化点 方案 说明
候选集缩小 先按类目/品牌过滤 减少需要比较的商品数量
向量索引加速 ES向量检索找相似候选 避免全量两两比较
分层去重 粗筛→精筛两阶段 先用简单规则过滤,再AI精判
增量去重 只对新数据去重 已去重商品不再重复计算
缓存相似度 Redis缓存已计算的相似度 避免重复计算
批量向量化 一次处理多条 提升向量化效率

分层去重流程:

相似度>=0.85

0.70<=相似度<0.85

相似度<0.70

新商品到来

第一层:粗筛
品牌相同? 类目相同? 价格接近?

通过?

独立入库

第二层:向量召回
标题向量检索Top-10候选

第三层:精判
多维度相似度计算
综合得分判定

判定结果

合并数据

标记待审核

独立入库

10.4 混合检索调优

检索路 权重 调优方向
BM25关键字 0.3 分词器优化、同义词扩展、停用词过滤
稠密向量语义 0.4 向量模型选择、Prompt优化、HNSW参数调整
稀疏向量词元 0.3 SPLADE模型微调、词元权重校准

10.5 数据更新策略

策略 频率 说明
全量更新 每日1次 凌晨低峰期执行
增量更新 每4小时 价格变动、新增商品
实时监控 每小时 热门商品价格追踪

10.6 性能优化

优化点 方案
搜索响应时间 Redis缓存热门搜索、ES查询优化、HNSW索引
向量化性能 批量向量化、GPU加速、向量缓存
采集效率 并发采集、代理池、限流控制
数据存储 冷热数据分离、索引分片
去重效率 分层去重、向量索引召回、相似度缓存

十一、风险与应对

风险 影响 应对措施
平台API限流 采集失败 多账号轮换、请求限流、重试机制
反爬封禁 数据缺失 代理池、请求间隔模拟、Cookie池
数据不一致 比价不准 数据校验、异常检测、人工审核
ES性能瓶颈 搜索慢 分片优化、缓存、读写分离

文档版本: v1.0
创建日期: 2026-06-11
最后更新: 2026-06-11

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐