Name Last Update
..
README.md Loading commit data...
generate_search_products_mapping.py Loading commit data...
search_products.json Loading commit data...
search_products.json.bak Loading commit data...
search_suggestions.json Loading commit data...

README.md

ES Mapping Configuration

概述

所有租户共享同一个 Elasticsearch mapping 结构。

当前目录采用“声明式 Python 规格 + 字段模板 + 最终 JSON 产物”的方式维护 search_products 的索引定义:

  • generate_search_products_mapping.py: 唯一的生成源,包含字段模板、语言列表、分析器配置和递归生成逻辑
  • search_products.json: 由脚本生成的完整 ES 索引配置,包括 settingsmappings
  • search_suggestions.json: 搜索建议索引配置

默认应修改生成脚本中的规格定义,而不是手工编辑 search_products.json

字段抽象

脚本从业务语义上抽象出 4 类文本模板:

  • all_language_text: 全语言字段,不带 keyword
  • all_language_text_with_keyword: 全语言字段,所有受支持语言都带 keyword
  • core_language_text: 核心索引语言字段,不带 keyword
  • core_language_text_with_keyword: 核心索引语言字段,核心语言都带 keyword

这里的“核心索引语言”不是因为系统只支持两种语言,而是因为所有店铺、所有商品都必须至少产出这两种语言的索引内容。目前核心索引语言固定为:

  • zh
  • en

“全语言”表示 mapping 为原始商品语言预留了更多语言槽位。商品实际灌入时,不要求每个字段把所有语言都填满,只要求:

  • 核心索引语言字段必须填充 zhen
  • 全语言字段必须填充 zhen
  • 如果商品原始语言属于受支持语言,还应额外填充对应的原始语言字段,例如 ru

当前字段大致分为几类:

  • 全语言字段:titlekeywordsbriefdescriptionvendorcategory_pathcategory_name_text
  • 核心索引语言字段:qanchorsenriched_tagsoption1_valuesoption2_valuesoption3_valuesenriched_attributes.value
  • 复合嵌套字段:image_embeddingspecificationsenriched_attributesskus
  • 其他标量字段:tenant_idspu_id、价格、库存、类目等

生成规则里的几个基础约束:

  • 中文字段使用 index_ik,并额外设置 search_analyzer: query_ik
  • 非中文语言使用各自的 Elasticsearch 内置 analyzer
  • with_keyword 的模板会为对应语言增加 .keyword
  • settings.analysisnormalizersimilarity 也属于生成结果的一部分,不能只维护 mappings.properties

索引灌入指引

基本原则

  1. 所有商品都必须生成核心索引语言版本,也就是 zhen
  2. 全语言字段除了必须有 zhen,还应尽量保留商品原始语言版本。
  3. 如果商品原始语言本身就是 zhen,则原文直接写入对应字段,另一种核心语言通过翻译补齐。
  4. 如果商品原始语言是 ru 这类受支持的非核心语言,则应同时写入原始语言字段和 zh/en 翻译结果。
  5. 如果某个值为空,不应写入伪造内容;应在上游清洗后决定是否跳过该字段。

核心索引语言字段

这类字段的目标是保证所有商品都至少能被中文和英文检索到。无论商品原始语言是什么,都应通过翻译或标准化得到 zhen 两份结果。

典型字段:

  • qanchors
  • enriched_tags
  • option1_values
  • option2_values
  • option3_values
  • enriched_attributes.value
  • enriched_taxonomy_attributes.value
  • specifications.value_text

category_pathoption*_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красный, синий

{
  "option1_values": {
    "zh": "红色, 蓝色",
    "en": "red, blue"
  }
}

示例:原始商品语言为俄语,类目路径为 Одежда > Женская одежда > Куртки

{
  "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

灌入规则:

  1. 找到商品原始语言,例如 ru
  2. 原文写入对应语言字段,例如 title.ru
  3. 将原文翻译成 zhen
  4. 分别写入 title.zhtitle.en

示例:原始商品语言为俄语,标题为 Женская зимняя куртка

{
  "title": {
    "zh": "女士冬季夹克",
    "en": "Women's winter jacket",
    "ru": "Женская зимняя куртка"
  }
}

示例:原始商品语言为俄语,类目名称为 Женские куртки

{
  "category_name_text": {
    "zh": "女式夹克",
    "en": "Women's jackets",
    "ru": "Женские куртки"
  }
}

示例:规格值 specifications.value_text / specifications.value_keyword

{
  "specifications": [
    {
      "sku_id": "sku-red-s",
      "name": "color",
      "value_keyword": "красный",
      "value_text": {
        "zh": "红色",
        "en": "red"
      }
    }
  ]
}

其中:

  • specifications.value_keyword 保存原始规格值,用于精确过滤 / 分面
  • specifications.value_text 保存 zh/en 两个核心索引语言版本,用于检索召回

原始语言为中文或英文时

如果原始语言就是核心索引语言之一,不需要额外再写第三份语言字段。

示例:原始语言为中文

{
  "title": {
    "zh": "女士冬季夹克",
    "en": "Women's winter jacket"
  },
  "option1_values": {
    "zh": "红色, 蓝色",
    "en": "red, blue"
  }
}

示例:原始语言为英文

{
  "title": {
    "zh": "女士冬季夹克",
    "en": "Women's winter jacket"
  },
  "vendor": {
    "zh": "北境服饰",
    "en": "Northern Apparel"
  }
}

不同字段的灌入方式

可以按下面的方式理解和实现:

  • 标量字段:直接写固定值,例如 tenant_idspu_idmin_price
  • 核心索引语言字段:只生成 zh/en
  • 全语言字段:生成 zh/en,再按原始语言补一个对应语种字段
  • 嵌套字段:对每个元素内部重复应用同样规则,例如 specifications[].value_textenriched_attributes[].value

推荐灌入流程

  1. 识别商品原始语言
  2. 提取原文标题、描述、类目、规格、属性、选项值等字段
  3. 生成 zhen 两份核心索引语言内容
  4. 对全语言字段,如果原始语言受支持,则额外写入原始语言字段
  5. 组装最终 ES 文档并写入索引

生成 Mapping

在仓库根目录执行:

source activate.sh
python mappings/generate_search_products_mapping.py > mappings/search_products.json

如果只想查看输出而不覆盖文件:

source activate.sh
python mappings/generate_search_products_mapping.py

如果想先生成到临时文件:

source activate.sh
python mappings/generate_search_products_mapping.py > mappings/search_products.generated.json

校验 Mapping

确认当前 search_products.json 是否与生成规则完全一致:

source activate.sh
python mappings/generate_search_products_mapping.py --check mappings/search_products.json

创建索引

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"])
mapping = load_mapping()
create_index_if_not_exists(es_client, "search_products", mapping)

修改 Mapping

推荐流程:

  1. 修改 mappings/generate_search_products_mapping.py
  2. 重新生成 mappings/search_products.json
  3. --check 或 diff 确认变更符合预期
  4. 重新创建索引并导入数据

注意:Elasticsearch 不支持直接修改已有字段的 mapping 类型,只能新增字段。如需修改字段类型,需要:

  1. 删除旧索引
  2. 使用新 mapping 创建索引
  3. 重新导入数据

字段说明

参考 docs/索引字段说明v2-mapping结构.md