相关性检索优化说明.md
6.29 KB
相关性检索优化说明
概述
本次优化将相关性检索从简单的 must 子句中的 multi_match 查询,改为使用 should 子句的多查询策略,参考了成熟的搜索实现,显著提升了检索效果。
主要改进
实现方式
本次优化采用精简实现,直接在 QueryParser 中集成必要的分析功能,不新增独立模块。
1. 查询结构优化
之前的结构(效果差):
{
"bool": {
"must": [
{
"multi_match": {
"query": "戏水动物",
"fields": ["title_zh^3.0", "brief_zh^1.5", ...],
"minimum_should_match": "67%",
"tie_breaker": 0.9,
"boost": 1,
"_name": "base_query"
}
}
]
}
}
优化后的结构(效果更好):
{
"bool": {
"should": [
{
"multi_match": {
"_name": "base_query",
"fields": ["title_zh^3.0", "brief_zh^1.5", ...],
"minimum_should_match": "75%",
"operator": "AND",
"query": "戏水动物",
"tie_breaker": 0.9
}
},
{
"multi_match": {
"_name": "base_query_trans_en",
"boost": 0.4,
"fields": ["title_en^3.0", ...],
"minimum_should_match": "75%",
"operator": "AND",
"query": "water sports",
"tie_breaker": 0.9
}
},
{
"multi_match": {
"query": "戏水动物",
"fields": ["title_zh^3.0", "brief_zh^1.5", ...],
"type": "phrase",
"slop": 2,
"boost": 1.0,
"_name": "phrase_query"
}
},
{
"multi_match": {
"query": "戏水 动物",
"fields": ["title_zh^3.0", "brief_zh^1.5", ...],
"operator": "AND",
"tie_breaker": 0.9,
"boost": 0.1,
"_name": "keywords_query"
}
}
],
"minimum_should_match": 1
}
}
2. 集成查询分析功能
在 QueryParser 中直接集成必要的分析功能:
- 关键词提取:使用 HanLP 提取查询中的名词(长度>1),用于关键词查询(可选,HanLP 不可用时降级)
- 查询类型判断:区分短查询和长查询
- Token 计数:用于判断查询长度
3. 多查询策略
3.1 基础查询(base_query)
- 使用
operator: "AND"确保所有词都必须匹配 minimum_should_match: "75%"提高匹配精度- 使用
tie_breaker: 0.9进行分数融合
3.2 翻译查询(base_query_trans_zh/en)
- 当查询语言不是中文/英文时,添加翻译查询
- 使用较低的 boost(0.4)避免过度影响
- 支持跨语言检索
3.3 短语查询(phrase_query)
- 针对短查询(token_count >= 2 且 is_short_query)
- 使用
type: "phrase"进行精确短语匹配 - 支持 slop(允许词序调整)
3.4 关键词查询(keywords_query)
- 使用 HanLP 提取的名词进行查询
- 仅在关键词长度合理时启用(避免关键词占查询比例过高)
- 使用较低的 boost(0.1)作为补充
3.5 长查询优化(long_query)
- 当前已禁用(参考实现中也是 False)
- 未来可根据需要启用
4. 字段映射优化
新增 _get_match_fields() 方法,支持:
- 根据语言动态获取匹配字段
- 区分全部字段(all_fields)和核心字段(core_fields)
- 核心字段用于短语查询和关键词查询,提高精度
实现细节
文件修改清单
- 修改文件:
query/query_parser.py- 添加关键词提取、查询类型判断等功能(HanLP 可选)search/es_query_builder.py- 实现 should 子句的多查询策略search/searcher.py- 传递 parsed_query 给查询构建器
关键参数说明
- minimum_should_match: 从 "67%" 提升到 "75%",提高匹配精度
- operator: 从默认改为 "AND",确保所有词都匹配
- tie_breaker: 保持 0.9,用于分数融合
- boost 值:
- base_query: 1.0(默认)
- translation queries: 0.4
- phrase_query: 1.0
- keywords_query: 0.1
依赖要求
- HanLP(可选):如果安装了
hanlp包,会自动启用关键词提取功能bash pip install hanlp
如果未安装,系统会自动降级到简单分析(基于空格分词),不影响基本功能。
- HanLP 模型:首次运行时会自动下载
- Tokenizer:
CTB9_TOK_ELECTRA_BASE_CRF - POS Tagger:
CTB9_POS_ELECTRA_SMALL
- Tokenizer:
配置说明
- 忽略关键词:在
_extract_keywords()方法中配置- 默认忽略:
['玩具']
- 默认忽略:
使用示例
基本使用
查询会自动使用优化后的策略,无需额外配置:
# 在 searcher.py 中,查询会自动使用优化策略
result = searcher.search(
query="戏水动物",
tenant_id="162",
size=10
)
查看分析结果
可以直接从 parsed_query 查看分析结果:
parsed_query = query_parser.parse("戏水动物")
print(f"关键词: {parsed_query.keywords}")
print(f"Token数: {parsed_query.token_count}")
print(f"短查询: {parsed_query.is_short_query}")
print(f"长查询: {parsed_query.is_long_query}")
性能考虑
- HanLP 初始化:采用懒加载,首次使用时才初始化
- 错误处理:HanLP 初始化失败或未安装时,系统会降级到简单分析(基于空格分词),不影响服务
- 代码精简:所有功能直接集成在
QueryParser中,无额外模块依赖
后续优化方向
- 长查询优化:可以启用长查询的特殊处理
- 意图识别:完善意图词典,提供更精准的意图识别
- 参数调优:根据实际效果调整 boost 值和 minimum_should_match
- A/B 测试:对比优化前后的检索效果
注意事项
- HanLP 依赖:HanLP 是可选的,如果未安装或初始化失败,系统会自动降级到简单分析,不会影响基本功能
- 性能影响:HanLP 分析会增加一定的处理时间,但采用懒加载机制
- 字段匹配:确保 ES 索引中存在对应的中英文字段
- 代码精简:所有功能都集成在现有模块中,保持代码结构简洁
参考
- 参考实现中的查询构建逻辑
- HanLP 官方文档:https://hanlp.hankcs.com/
- Elasticsearch multi_match 查询文档