59b0a342
tangwang
创建手写 mapping JSON
|
1
2
3
4
|
# ES Mapping Configuration
## 概述
|
fca871fb
tangwang
索引字段修改
|
5
|
所有租户共享同一个 Elasticsearch mapping 结构。
|
59b0a342
tangwang
创建手写 mapping JSON
|
6
|
|
fca871fb
tangwang
索引字段修改
|
7
|
当前目录采用“声明式 Python 规格 + 字段模板 + 最终 JSON 产物”的方式维护 `search_products` 的索引定义:
|
59b0a342
tangwang
创建手写 mapping JSON
|
8
|
|
fca871fb
tangwang
索引字段修改
|
9
10
11
|
- `generate_search_products_mapping.py`: 唯一的生成源,包含字段模板、语言列表、分析器配置和递归生成逻辑
- `search_products.json`: 由脚本生成的完整 ES 索引配置,包括 `settings` 和 `mappings`
- `search_suggestions.json`: 搜索建议索引配置
|
59b0a342
tangwang
创建手写 mapping JSON
|
12
|
|
fca871fb
tangwang
索引字段修改
|
13
|
默认应修改生成脚本中的规格定义,而不是手工编辑 `search_products.json`。
|
59b0a342
tangwang
创建手写 mapping JSON
|
14
|
|
fca871fb
tangwang
索引字段修改
|
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
## 字段抽象
脚本从业务语义上抽象出 4 类文本模板:
- `all_language_text`: 全语言字段,不带 `keyword`
- `all_language_text_with_keyword`: 全语言字段,所有受支持语言都带 `keyword`
- `core_language_text`: 核心索引语言字段,不带 `keyword`
- `core_language_text_with_keyword`: 核心索引语言字段,核心语言都带 `keyword`
这里的“核心索引语言”不是因为系统只支持两种语言,而是因为所有店铺、所有商品都必须至少产出这两种语言的索引内容。目前核心索引语言固定为:
- `zh`
- `en`
“全语言”表示 mapping 为原始商品语言预留了更多语言槽位。商品实际灌入时,不要求每个字段把所有语言都填满,只要求:
- 核心索引语言字段必须填充 `zh` 和 `en`
- 全语言字段必须填充 `zh` 和 `en`
- 如果商品原始语言属于受支持语言,还应额外填充对应的原始语言字段,例如 `ru`
当前字段大致分为几类:
|
d350861f
tangwang
索引结构修改
|
37
38
|
- 全语言字段:`title`、`keywords`、`brief`、`description`、`vendor`、`category_path`、`category_name_text`
- 核心索引语言字段:`qanchors`、`enriched_tags`、`option1_values`、`option2_values`、`option3_values`、`enriched_attributes.value`
|
fca871fb
tangwang
索引字段修改
|
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
|
- 复合嵌套字段:`image_embedding`、`specifications`、`enriched_attributes`、`skus`
- 其他标量字段:`tenant_id`、`spu_id`、价格、库存、类目等
生成规则里的几个基础约束:
- 中文字段使用 `index_ik`,并额外设置 `search_analyzer: query_ik`
- 非中文语言使用各自的 Elasticsearch 内置 analyzer
- 带 `with_keyword` 的模板会为对应语言增加 `.keyword`
- `settings.analysis`、`normalizer`、`similarity` 也属于生成结果的一部分,不能只维护 `mappings.properties`
## 索引灌入指引
### 基本原则
1. 所有商品都必须生成核心索引语言版本,也就是 `zh` 和 `en`。
2. 全语言字段除了必须有 `zh` 和 `en`,还应尽量保留商品原始语言版本。
3. 如果商品原始语言本身就是 `zh` 或 `en`,则原文直接写入对应字段,另一种核心语言通过翻译补齐。
4. 如果商品原始语言是 `ru` 这类受支持的非核心语言,则应同时写入原始语言字段和 `zh/en` 翻译结果。
5. 如果某个值为空,不应写入伪造内容;应在上游清洗后决定是否跳过该字段。
### 核心索引语言字段
这类字段的目标是保证所有商品都至少能被中文和英文检索到。无论商品原始语言是什么,都应通过翻译或标准化得到 `zh` 和 `en` 两份结果。
典型字段:
- `qanchors`
|
d350861f
tangwang
索引结构修改
|
66
|
- `enriched_tags`
|
fca871fb
tangwang
索引字段修改
|
67
68
69
70
|
- `option1_values`
- `option2_values`
- `option3_values`
- `enriched_attributes.value`
|
78cdef1c
tangwang
添加字段enriched_taxo...
|
71
|
- `enriched_taxonomy_attributes.value`
|
d350861f
tangwang
索引结构修改
|
72
|
- `specifications.value_text`
|
fca871fb
tangwang
索引字段修改
|
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
|
以 `category_path` 和 `option*_values` 为例,核心语言灌入结果应至少包含:
- `category_path.zh`
- `category_path.en`
- `option1_values.zh`
- `option1_values.en`
- `option2_values.zh`
- `option2_values.en`
- `option3_values.zh`
- `option3_values.en`
示例:原始商品语言为俄语,原始 `option1_values` 为 `красный, синий`
```json
{
"option1_values": {
"zh": "红色, 蓝色",
"en": "red, blue"
}
}
```
示例:原始商品语言为俄语,类目路径为 `Одежда > Женская одежда > Куртки`
```json
{
"category_path": {
"zh": "服饰 > 女装 > 夹克",
"en": "Apparel > Women's Clothing > Jackets",
"ru": "Одежда > Женская одежда > Куртки"
}
}
```
注意:`category_path` 在 mapping 上属于全语言字段,但在灌入规范上依然要求 `zh/en` 必填。
### 全语言字段
这类字段既要保证 `zh/en` 两个核心索引语言可用,也要尽量保留商品原始语言,以便原语种召回和更自然的检索。
典型字段:
- `title`
- `keywords`
- `brief`
- `description`
- `vendor`
- `category_path`
- `category_name_text`
|
fca871fb
tangwang
索引字段修改
|
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
|
灌入规则:
1. 找到商品原始语言,例如 `ru`
2. 原文写入对应语言字段,例如 `title.ru`
3. 将原文翻译成 `zh` 和 `en`
4. 分别写入 `title.zh` 和 `title.en`
示例:原始商品语言为俄语,标题为 `Женская зимняя куртка`
```json
{
"title": {
"zh": "女士冬季夹克",
"en": "Women's winter jacket",
"ru": "Женская зимняя куртка"
}
}
```
示例:原始商品语言为俄语,类目名称为 `Женские куртки`
```json
{
"category_name_text": {
"zh": "女式夹克",
"en": "Women's jackets",
"ru": "Женские куртки"
}
}
```
|
d350861f
tangwang
索引结构修改
|
155
|
示例:规格值 `specifications.value_text` / `specifications.value_keyword`
|
fca871fb
tangwang
索引字段修改
|
156
157
158
159
160
161
162
|
```json
{
"specifications": [
{
"sku_id": "sku-red-s",
"name": "color",
|
d350861f
tangwang
索引结构修改
|
163
164
|
"value_keyword": "красный",
"value_text": {
|
fca871fb
tangwang
索引字段修改
|
165
|
"zh": "红色",
|
d350861f
tangwang
索引结构修改
|
166
|
"en": "red"
|
fca871fb
tangwang
索引字段修改
|
167
168
169
170
171
172
|
}
}
]
}
```
|
d350861f
tangwang
索引结构修改
|
173
174
175
176
177
|
其中:
- `specifications.value_keyword` 保存原始规格值,用于精确过滤 / 分面
- `specifications.value_text` 保存 `zh/en` 两个核心索引语言版本,用于检索召回
|
fca871fb
tangwang
索引字段修改
|
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
218
|
### 原始语言为中文或英文时
如果原始语言就是核心索引语言之一,不需要额外再写第三份语言字段。
示例:原始语言为中文
```json
{
"title": {
"zh": "女士冬季夹克",
"en": "Women's winter jacket"
},
"option1_values": {
"zh": "红色, 蓝色",
"en": "red, blue"
}
}
```
示例:原始语言为英文
```json
{
"title": {
"zh": "女士冬季夹克",
"en": "Women's winter jacket"
},
"vendor": {
"zh": "北境服饰",
"en": "Northern Apparel"
}
}
```
### 不同字段的灌入方式
可以按下面的方式理解和实现:
- 标量字段:直接写固定值,例如 `tenant_id`、`spu_id`、`min_price`
- 核心索引语言字段:只生成 `zh/en`
- 全语言字段:生成 `zh/en`,再按原始语言补一个对应语种字段
|
d350861f
tangwang
索引结构修改
|
219
|
- 嵌套字段:对每个元素内部重复应用同样规则,例如 `specifications[].value_text`、`enriched_attributes[].value`
|
fca871fb
tangwang
索引字段修改
|
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
### 推荐灌入流程
1. 识别商品原始语言
2. 提取原文标题、描述、类目、规格、属性、选项值等字段
3. 生成 `zh` 和 `en` 两份核心索引语言内容
4. 对全语言字段,如果原始语言受支持,则额外写入原始语言字段
5. 组装最终 ES 文档并写入索引
## 生成 Mapping
在仓库根目录执行:
```bash
source activate.sh
python mappings/generate_search_products_mapping.py > mappings/search_products.json
```
如果只想查看输出而不覆盖文件:
```bash
source activate.sh
python mappings/generate_search_products_mapping.py
```
如果想先生成到临时文件:
```bash
source activate.sh
python mappings/generate_search_products_mapping.py > mappings/search_products.generated.json
```
## 校验 Mapping
确认当前 `search_products.json` 是否与生成规则完全一致:
```bash
source activate.sh
python mappings/generate_search_products_mapping.py --check mappings/search_products.json
```
## 创建索引
|
59b0a342
tangwang
创建手写 mapping JSON
|
262
263
264
265
266
267
|
```python
from indexer.mapping_generator import load_mapping, create_index_if_not_exists
from utils.es_client import ESClient
es_client = ESClient(hosts=["http://localhost:9200"])
|
fca871fb
tangwang
索引字段修改
|
268
|
mapping = load_mapping()
|
59b0a342
tangwang
创建手写 mapping JSON
|
269
270
271
|
create_index_if_not_exists(es_client, "search_products", mapping)
```
|
fca871fb
tangwang
索引字段修改
|
272
273
274
275
276
277
278
279
|
## 修改 Mapping
推荐流程:
1. 修改 `mappings/generate_search_products_mapping.py`
2. 重新生成 `mappings/search_products.json`
3. 用 `--check` 或 diff 确认变更符合预期
4. 重新创建索引并导入数据
|
59b0a342
tangwang
创建手写 mapping JSON
|
280
|
|
fca871fb
tangwang
索引字段修改
|
281
|
注意:Elasticsearch 不支持直接修改已有字段的 mapping 类型,只能新增字段。如需修改字段类型,需要:
|
59b0a342
tangwang
创建手写 mapping JSON
|
282
|
|
59b0a342
tangwang
创建手写 mapping JSON
|
283
|
1. 删除旧索引
|
fca871fb
tangwang
索引字段修改
|
284
|
2. 使用新 mapping 创建索引
|
59b0a342
tangwang
创建手写 mapping JSON
|
285
286
287
288
289
|
3. 重新导入数据
## 字段说明
参考 `docs/索引字段说明v2-mapping结构.md`
|