如何为Elasticsearch指定字段的mapping添加lowercase normalizer?
错误根因
- 用
putSettings接口提交字段映射配置是错误的:putSettings仅用于修改索引的全局配置(比如分词器、分片数等),字段映射属于mapping范畴,提交到settings接口会被ES识别为无效参数,触发第一个报错。 - 用
putMappings报错是因为ES 7.x要求字段定义必须包裹在properties节点下,你直接把字段配置放在请求根节点,导致ES无法解析映射结构,触发第二个报错。
解决步骤
步骤1:新增/更新索引的分词配置
如果你的lowercase_normalizer、自定义分词器还没有配置到目标索引中,需要先更新索引设置,这类静态配置更新前需要先关闭索引:
// 关闭索引 await this.getClient().indices.close({index: indexName}); // 更新索引设置,配置自定义normalizer和分词器 await this.getClient().indices.putSettings({ index: indexName, body: { index: { analysis: { filter: { ngram_custom: { type: "edge_ngram", min_gram: "1", max_gram: "15", } }, tokenizer: { // 请补充你自定义software_tokenizer的完整配置 software_tokenizer: {} }, normalizer: { lowercase_normalizer: { filter: ["lowercase"] } }, analyzer: { // 请补充你defaultAnalyzer的完整配置 software_search_analyzer: {}, software_analyzer: { type: "custom", tokenizer: "software_tokenizer", char_filter: ["html_strip"], filter: ["lowercase", "ngram_custom"] } } } } } }); // 重新打开索引 await this.getClient().indices.open({index: indexName});
等待索引状态恢复为green后再执行后续操作。
步骤2:更新字段映射
调用putMappings接口时,将字段配置放在properties节点下即可:
await this.getClient().indices.putMapping({ index: indexName, body: { properties: { // 注意这里的字段名要和你实际需要更新的字段一致,之前报错里出现的是publisher,按需修改 softwarePublisher: { type: "text", fields: { ngram: { type: "text", analyzer: "software_analyzer", search_analyzer: "software_search_analyzer", }, raw: { type: "keyword", }, rawl: { type: "keyword", normalizer: "lowercase_normalizer", } } } } } });
步骤3:刷新历史数据索引
新增的rawl子字段不会自动对历史数据生成索引,调用update_by_query接口刷新即可:
await this.getClient().updateByQuery({ index: indexName, conflicts: "proceed" });
注意事项
- 只要你新增的字段配置和原有映射没有冲突,ES会自动合并映射,不需要你重新定义全部旧字段。
- 如果你的自定义分词器、normalizer已经配置在索引中,可以跳过步骤1直接执行步骤2。
内容的提问来源于stack exchange,提问作者Tlaloc-ES
相关产品推荐
相关产品推荐

