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


一、系统架构总览

数据存储层

Elasticsearch
搜索+向量索引

MySQL
业务数据/元数据

Redis
缓存/分布式锁/限流

数据处理层

数据采集
Scheduler

数据清洗
ETL管道

向量化
Embedding

索引构建
ES写入

服务层

搜索服务

比价服务

商品服务

前端应用层

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


二、技术栈选型

层级技术组件说明
后端框架Spring Boot 3.xJava主服务
搜索引擎阿里云 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
官方开放平台1688Open API (TOP协议)P0
官方开放平台抖音电商Open API (OAuth2.0)P1
第三方聚合万邦开放平台REST APIP1
第三方聚合聚美数仓REST APIP1
自研爬虫各平台Selenium WebDriverP2

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)
基础URLhttps://api.jd.com/routerjson
核心接口jingdong.ware.search(商品搜索)
限流策略单应用QPS限制,需控制请求频率
数据返回JSON格式,包含商品ID、标题、价格、图片等

接入要点:

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

接入要点:

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

接入要点:

  • URL路径包含appKey和接口名称
  • 批发商品有起订量、阶梯价格等特殊字段
  • 部分数据需要企业账号权限
3.3.4 抖音电商开放平台
项目说明
认证方式OAuth2.0
Token获取AppID + AppSecret 换取 AccessToken
基础URLhttps://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_idwareIdgoodsIdofferIdproductId
titlewareNamegoodsNamesubjecttitle
pricejdPriceminGroupPricepriceRange.minprice
original_pricemarketPricemarketPriceoriginalPriceoriginPrice
sales_countcommentCountsalesTipamountOnSale-
review_countcommentCount---
ratinggoodRate--rate
brandbrandNamebrandNamebrandbrandName
categorycategoryIdcategoryIdcategorycategoryId
main_imageimageInfogoodsThumbnailUrlimageUrls[0]mainImg
imagesimageInfoListgoodsGalleryUrlsimageUrlsdetailImgList
shop_nameshopNamemallNamecompanyNameshopName
shop_idshopIdmallIdmemberIdshopId
product_urlwareUrlgoodsUrlofferDetailUrlproductUrl

类型转换规则:

源类型目标类型转换规则
字符串价格 “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手机📱 → 手机
多余空格合并连续空格合并为单个空格苹果 手机 → 苹果手机
广告词过滤移除营销类词汇【包邮】正品手机 → 手机
全角转半角全角数字/字母转半角123 → 123
大小写统一品牌名保留原样,其他转小写APPLE → apple

广告词黑名单:

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

(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_idString平台商品唯一ID
platformEnum来源平台(jd/pdd/1688/douyin)
titleString商品标题
subtitleString副标题/卖点
descriptionString商品描述
价格信息priceFloat当前售价(元)
original_priceFloat原价/划线价
currencyString货币单位(默认CNY)
销售信息sales_countInteger销量
review_countInteger评论数
ratingFloat评分(1-5)
分类信息categoryString商品类目
brandString品牌
tagsList标签列表
图片信息main_imageString主图URL
imagesList图片URL列表
商家信息shop_nameString店铺名称
shop_idString店铺ID
shop_ratingFloat店铺评分
链接信息product_urlString商品详情页URL
affiliate_urlString推广链接
时间信息crawl_timeDateTime爬取时间
updated_atDateTime更新时间
质量信息quality_scoreFloat质量评分(0-100)
quality_levelEnum质量等级(A/B/C/D)
向量信息title_embeddingFloat[]标题向量(1024维)
desc_embeddingFloat[]描述向量(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_idkeyword-精确匹配
platformkeyword-精确匹配/过滤
titletextik_max_word全文检索
title.keywordkeyword-精确匹配
title.dense_vectordense_vector-稠密向量(1024维)
title.sparse_vectorsparse_vector-稀疏向量
descriptiontextik_max_word全文检索
pricefloat-数值范围查询
sales_countinteger-数值排序
categorykeyword-分类过滤
brandkeyword-品牌过滤
tagskeyword-标签过滤
crawl_timedate-时间范围查询
desc.dense_vectordense_vector-描述稠密向量(1024维)

5.2 向量化服务

向量模型选型:

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

向量化流程:

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

文本预处理

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

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

原始标题文本

描述清洗后文本

【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/searchGET商品混合检索公开
/api/v1/products/compareGET多平台比价公开
/api/v1/products/{platform}/{id}GET商品详情公开
/api/v1/products/hotGET热门商品公开
/api/v1/categoriesGET类目列表公开
/api/v1/price/history/{platform}/{id}GET价格历史公开

8.2 搜索接口说明

请求参数:

参数类型必填说明
queryString是搜索关键词
platformsString否平台过滤,逗号分隔
min_priceFloat否最低价格
max_priceFloat否最高价格
brandString否品牌过滤
categoryString否类目过滤
sort_byString否排序方式
pageInteger否页码,默认1
page_sizeInteger否每页数量,默认20

响应结构:

字段类型说明
totalInteger总结果数
pageInteger当前页码
page_sizeInteger每页数量
resultsArray商品列表

商品对象字段:

字段类型说明
product_idString商品ID
platformString来源平台
titleString商品标题
priceFloat价格
original_priceFloat原价
sales_countInteger销量
ratingFloat评分
brandString品牌
main_imageString主图
product_urlString商品链接
shop_nameString店铺名称
scoreFloat相关度得分

8.3 比价接口说明

请求参数:

参数类型必填说明
queryString是商品搜索词
platformsString否指定平台

响应结构:

字段类型说明
queryString搜索词
comparisonArray各平台比价结果
best_dealObject最优购买推荐

九、部署架构

9.1 服务组件

服务端口说明
Elasticsearch9200搜索引擎
MySQL3306关系型数据库
Redis6379缓存服务
XXL-JOB Admin8081任务调度中心
后端API服务8080主服务
数据采集服务-后台Worker
Nginx80/443反向代理

9.3 资源配置建议

组件CPU内存磁盘
Elasticsearch4核+8GB+SSD 100GB+
MySQL2核+4GB+SSD 50GB+
Redis1核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索引参数:

参数值说明
m16每个节点的最大连接数
ef_construction100构建索引时的搜索深度
ef_search50查询时的搜索深度,越大越准越慢

优势与局限:

  • 优势:语义理解强,能匹配字面不同但含义相同的商品
  • 局限:计算开销大,对精确匹配不如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得分
商品A1321/61 + 1/63 + 1/62 = 0.0487
商品B2151/62 + 1/61 + 1/65 = 0.0481
商品C5211/65 + 1/62 + 1/61 = 0.0478
商品D3841/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.0Apple vs Apple
别名匹配0.9Apple vs 苹果
包含关系0.7Apple vs Apple授权
不同0.0Apple vs Samsung

品牌别名映射表:

标准品牌别名
Apple苹果、iPhone、iPad
Huawei华为
Xiaomi小米、MI
OPPOOPPO、欧珀
vivovivo、维沃
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.3SPLADE模型微调、词元权重校准

10.5 数据更新策略

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

10.6 性能优化

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

十一、风险与应对

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

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

Logo

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

更多推荐