Blame view

docs/相关性检索优化说明.md 6.32 KB
7bc756c5   tangwang   优化 ES 查询构建
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
  # 相关性检索优化说明
  
  ## 概述
  
  本次优化将相关性检索从简单的 `must` 子句中的 `multi_match` 查询,改为使用 `should` 子句的多查询策略,参考了成熟的搜索实现,显著提升了检索效果。
  
  ## 主要改进
  
  ## 实现方式
  
  本次优化采用精简实现,直接在 `QueryParser` 中集成必要的分析功能,不新增独立模块。
  
  ### 1. 查询结构优化
  
  **之前的结构**(效果差):
  ```json
  {
    "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"
          }
        }
      ]
    }
  }
  ```
  
  **优化后的结构**(效果更好):
  ```json
  {
    "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 (e.g. animals playing with water)",
            "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)
  - 核心字段用于短语查询和关键词查询,提高精度
  
  ## 实现细节
  
  ### 文件修改清单
  
  1. **修改文件**
     - `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`
  
  ### 配置说明
  
  - **忽略关键词**:在 `_extract_keywords()` 方法中配置
    - 默认忽略:`['玩具']`
  
  ## 使用示例
  
  ### 基本使用
  
  查询会自动使用优化后的策略,无需额外配置:
  
  ```python
  # 在 searcher.py 中,查询会自动使用优化策略
  result = searcher.search(
      query="戏水动物",
      tenant_id="162",
      size=10
  )
  ```
  
  ### 查看分析结果
  
  可以直接从 `parsed_query` 查看分析结果:
  
  ```python
  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}")
  ```
  
  ## 性能考虑
  
  1. **HanLP 初始化**:采用懒加载,首次使用时才初始化
  2. **错误处理**:HanLP 初始化失败或未安装时,系统会降级到简单分析(基于空格分词),不影响服务
  3. **代码精简**:所有功能直接集成在 `QueryParser` 中,无额外模块依赖
  
  ## 后续优化方向
  
  1. **长查询优化**:可以启用长查询的特殊处理
  2. **意图识别**:完善意图词典,提供更精准的意图识别
  3. **参数调优**:根据实际效果调整 boost 值和 minimum_should_match
  4. **A/B 测试**:对比优化前后的检索效果
  
  ## 注意事项
  
  1. **HanLP 依赖**:HanLP 是可选的,如果未安装或初始化失败,系统会自动降级到简单分析,不会影响基本功能
  2. **性能影响**:HanLP 分析会增加一定的处理时间,但采用懒加载机制
  3. **字段匹配**:确保 ES 索引中存在对应的中英文字段
  4. **代码精简**:所有功能都集成在现有模块中,保持代码结构简洁
  
  ## 参考
  
  - 参考实现中的查询构建逻辑
  - HanLP 官方文档:https://hanlp.hankcs.com/
  - Elasticsearch multi_match 查询文档