在中文搜索场景中,用户经常使用拼音输入(如 “iPhone”、“pingguo”)来搜索中文内容(如“苹果手机”)。为了提升用户体验,Elasticsearch 可通过 拼音分词器 + Completion Suggester 实现 拼音补全(Pinyin Completion) 功能。

本文提供一套 完整、可落地的 Elasticsearch 拼音补全配置模板,支持:

  • 中文输入 → 中文补全
  • 拼音输入 → 中文补全
  • 拼音首字母输入 → 中文补全
  • 自动纠错与模糊匹配

一、前置准备

1. 安装拼音分词插件

Elasticsearch 官方不自带拼音分词器,需安装第三方插件:

# 进入 Elasticsearch 插件目录
cd /usr/share/elasticsearch# 安装拼音分词器(根据 ES 版本选择)
bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-pinyin/releases/download/v8.11.0/elasticsearch-analysis-pinyin-8.11.0-linux-x86_64.zip

✅ 支持版本:6.x ~ 8.x,GitHub 项目地址

重启 Elasticsearch 使插件生效。


二、索引配置模板

PUT /products-pinyin
{"settings": {"analysis": {"analyzer": {"pinyin_analyzer": {"type": "custom","tokenizer": "pinyin","filter": ["lowercase"]}},"tokenizer": {"pinyin": {"type": "pinyin","keep_separate_first_letter": false,"keep_full_pinyin": true,"keep_original": true,"limit_first_letter_length": 16,"lowercase": true,"remove_duplicated_term": true}}}},"mappings": {"properties": {"title": {"type": "text","analyzer": "ik_max_word","fields": {"pinyin": {"type": "text","analyzer": "pinyin_analyzer"}}},"suggest": {"type": "completion","analyzer": "simple","preserve_separators": true,"preserve_position_increments": true,"max_input_length": 50},"suggest_pinyin": {"type": "completion","analyzer": "pinyin_analyzer","preserve_separators": false,"preserve_position_increments": false,"max_input_length": 50}}}
}

三、字段说明

字段用途
title原始文本,用于全文搜索
title.pinyin用于拼音搜索(如 match: { "title.pinyin": "pingguo" }
suggest支持中文输入补全(如“苹” → “苹果手机”)
suggest_pinyin支持拼音输入补全(如“ping” → “苹果手机”)

四、写入文档示例

PUT /products-pinyin/_doc/1
{"title": "苹果手机 iPhone 15","suggest": {"input": ["苹果手机","iPhone 15","苹果","手机"],"weight": 30},"suggest_pinyin": {"input": ["pingguoshouji","yinguoshouji","pingguo","shouji","pgs","pg"],"weight": 30}
}

input 列表包含:

  • 完整拼音:pingguoshouji
  • 首字母:pgspg
  • 分词拼音:pingguo, shouji

五、查询方式

1. 中文前缀补全

POST /products-pinyin/_search
{"suggest": {"text": "苹","completion": {"field": "suggest"}}
}

返回:

"suggest": [{"text": "苹","options": [{ "text": "苹果手机", "score": 30 }]}
]

2. 拼音前缀补全

POST /products-pinyin/_search
{"suggest": {"text": "ping","completion": {"field": "suggest_pinyin"}}
}

返回:

"options": [{ "text": "pingguoshouji", "score": 30 }
]

⚠️ 返回的是拼音,需在应用层映射回原始标题。

✅ 建议:在 suggest_pinyin_source 中存储原始 title

"suggest_pinyin": {"input": ["pingguo"],"weight": 30,"_source": "苹果手机 iPhone 15"
}

3. 拼音首字母补全

POST /products-pinyin/_search
{"suggest": {"text": "pgs","completion": {"field": "suggest_pinyin"}}
}

只要 input 中包含 pgs,即可匹配。


4. 模糊拼音补全(支持纠错)

"suggest": {"text": "pinggou","completion": {"field": "suggest_pinyin","fuzzy": {"fuzziness": 1,"transpositions": true}}
}

可匹配 pingguo(编辑距离为 1)。


六、优化建议 ✅

场景建议
输入性能预生成拼音和首字母,避免运行时计算
存储空间suggest_pinyin.input 可能较多,控制 max_input_length
权重控制热门商品设置更高 weight
缓存应用层缓存高频拼音前缀(如“i”, “ip”, “iph”)
多语言支持英文、拼音混合输入

七、完整补全流程(应用层)

def get_suggestions(user_input):suggestions = []# 1. 如果是中文,查 suggestif is_chinese(user_input):res = es.search(index="products-pinyin", suggest={"text": user_input, "completion": {"field": "suggest"}})for opt in res['suggest'][0]['options']:suggestions.append(opt['text'])# 2. 如果是拼音,查 suggest_pinyinelif is_pinyin(user_input):res = es.search(index="products-pinyin", suggest={"text": user_input, "completion": {"field": "suggest_pinyin"}, "fuzzy": {"fuzziness": 1}})for opt in res['suggest'][0]['options']:# 从 _source 或映射表获取原始标题original = get_title_by_pinyin(opt['text'])if original not in suggestions:suggestions.append(original)return suggestions[:10]

八、扩展建议

场景建议方案
动态拼音生成写入时用 Ingest Pipeline 自动生成拼音
拼音 + 中文混合补全使用 multi_match 查询 title.pinyintitle
个性化补全结合用户历史行为调整 weight
冷启动问题初始填充运营配置的热门词
性能监控监控 suggest 查询延迟与命中率

九、Ingest Pipeline 自动生成拼音(可选)

PUT /_ingest/pipeline/add_pinyin_suggest
{"description": "自动添加拼音补全字段","processors": [{"script": {"lang": "painless","source": """ctx.suggest_pinyin = [];def inputs = [ctx.title];// 可调用外部服务生成拼音// 此处简化为固定值ctx.suggest_pinyin.add('pingguoshouji');ctx.suggest_pinyin.add('pgs');"""}}]
}

写入时使用:

PUT /products-pinyin/_doc/2?pipeline=add_pinyin_suggest
{"title": "华为手机"
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/919244.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/919244.shtml
英文地址,请注明出处:http://en.pswp.cn/news/919244.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Redis面试精讲 Day 23:Redis与数据库数据一致性保障

【Redis面试精讲 Day 23】Redis与数据库数据一致性保障 在“Redis面试精讲”系列的第23天,我们将深入探讨Redis与数据库数据一致性保障这一在高并发分布式系统中极为关键的技术难题。该主题是面试中的高频压轴题,常出现在中高级后端开发、架构师岗位的考…

HTML <link rel=“preload“>:提前加载关键资源的性能优化利器

在网页性能优化中&#xff0c;“资源加载时机”是影响用户体验的关键因素——一个延迟加载的核心CSS可能导致页面“闪白”&#xff0c;一段未及时加载的关键JS可能让交互按钮失效。传统的资源加载方式&#xff08;如<link>加载CSS、<script>加载JS&#xff09;依赖…

WPF加载记忆上次图像

问题点使用MVVM先viewModel构造函数然后才Loaded事件,但Loaded事情时halcon控件没有加载完毕。Window_ContentRendered事件中halcon控件才有了句柄。解决问题1.viewModel函数中调用相机的类获取相机名(在这里是为了MVVM中以后可以做其它的事情如识别二维码)2.在Window_ContentR…

AT89C52单片机介绍

目录 1AT89C52原理图及结构框图 1.1 原理图 1.2 AT89C52 结构框图 1.2.1 8 位 CPU 1.2.2 存储器 1.2.3 I/O 端口 1.2.4 定时器 / 计数器 1.2.5 串行通信接口 1.2.6 中断系统 1.2.7 时钟与复位 1.2.8 总线结构 1.2.9 特殊功能寄存器区 2 AT89C52引脚介绍(PDIP) …

联网车辆功能安全和网络安全的挑战与当前解决方案

摘要在过去的二十年里&#xff0c;数字化重塑了我们的日常生活&#xff0c;汽车行业也身处这一变革之中。如今的车辆正变得日益智能且联网&#xff0c;具备了更多的安全和便捷功能&#xff08;如自动紧急制动、自适应巡航控制&#xff09;。下一代车辆将实现高度自动化乃至 5 级…

网络安全(Java语言)脚本 汇总(二)

文章目录目录遍历漏洞扫描器源代码思路一、核心功能二、依赖库三、核心流程四、关键方法五、数据结构六、输出信息目录遍历漏洞扫描器 源代码 /*** description : 目录遍历漏洞扫描器* 注意; 在输入URL时 要求必须保存 ?page 的末尾 才能保证路径合成的有效性*//*** desc…

基于 ArcFace/ArcMargin 损失函数的深度特征学习高性能人脸识别解决方案

要实现当前最先进的人脸识别系统,我们需要采用业界公认性能最佳的算法框架,主要包括基于 ArcFace/ArcMargin 损失函数的深度特征学习、MTCNN 人脸检测与对齐以及高效特征检索三大核心技术。以下是优化后的解决方案: 核心优化点说明 算法选择:采用 ArcFace(Additive Angul…

Sql server 查询每个表大小

在SQL Server中&#xff0c;你可以通过查询系统视图和系统表来获取数据库中每个表的大小。这可以通过几种不同的方式来实现&#xff0c;下面是一些常用的方法&#xff1a;方法1&#xff1a;使用sp_spaceused存储过程sp_spaceused是一个内置的存储过程&#xff0c;可以用来显示数…

react 错误边界

注意点&#xff1a; 类组件是可以和函数式组件混合写的&#xff01;&#xff01;&#xff01;getDerivedStateFromError是静态的&#xff0c;避免副作用&#xff0c;如果想将错误上报到服务器&#xff0c;则去componentDidCatch里去处理。getDerivedStateFromError直接返回{ ha…

自定义 VSCode 标题栏以区分不同版本

自定义 VSCode 标题栏以区分不同版本 当您在同一台计算机上使用多个 Visual Studio Code 版本时&#xff0c;自定义窗口标题栏是一个有效的方法&#xff0c;可以帮助您快速区分它们。 为何需要区分多个 VSCode 版本&#xff1f; 在同一台电脑上安装和使用多个 VSCode 实例是很常…

失败存储:查看未成功的内容

作者&#xff1a;来自 Elastic James Baiera 及 Graham Hudgins 了解失败存储&#xff0c;这是 Elastic Stack 的一项新功能&#xff0c;用于捕获和索引之前丢失的事件。 想获得 Elastic 认证吗&#xff1f;看看下一期 Elasticsearch Engineer 培训什么时候开始&#xff01; E…

基于Spring Boot+Vue的莱元元电商数据分析系统 销售数据分析 天猫电商订单系统

&#x1f525;作者&#xff1a;it毕设实战小研&#x1f525; &#x1f496;简介&#xff1a;java、微信小程序、安卓&#xff1b;定制开发&#xff0c;远程调试 代码讲解&#xff0c;文档指导&#xff0c;ppt制作&#x1f496; 精彩专栏推荐订阅&#xff1a;在下方专栏&#x1…

Node.js/Python 实战:封装淘宝商品详情 API 客户端库(SDK)

在开发电商相关应用时&#xff0c;我们经常需要与淘宝 API 交互获取商品数据。直接在业务代码中处理 API 调用逻辑会导致代码冗余且难以维护。本文将实战演示如何使用 Node.js 和 Python 封装一个高质量的淘宝商品详情 API 客户端库&#xff08;SDK&#xff09;&#xff0c;使开…

【Docker】关于hub.docker.com,无法打开,国内使用dockers.xuanyuan.me搜索容器镜像、查看容器镜像的使用文档

&#x1f527; 一、国内镜像搜索替代方案 国内镜像源网站 毫秒镜像&#xff1a;支持镜像搜索&#xff08;如 https://dockers.xuanyuan.me&#xff09;&#xff0c;提供中文文档服务&#xff08;https://dockerdocs.xuanyuan.me&#xff09;&#xff0c;可直接搜索镜像名称并…

2025盛夏AI热浪:八大技术浪潮重构数字未来

——从大模型革命到物理智能&#xff0c;AI如何重塑产业与人机关系&#x1f31f; 引言&#xff1a;AI从“技术爆炸”迈向“应用深水区」代码示例&#xff1a;AI商业化闭环验证模型# 验证AI商业化闭环的飞轮效应 def validate_ai_flywheel(compute_invest, app_adoption): re…

从希格斯玻色子到 QPU:C++ 的跨维度征服

一、引言&#xff1a;粒子物理与量子计算的交汇点在当代物理学和计算机科学的前沿领域&#xff0c;希格斯玻色子研究与量子计算技术的交汇正形成一个激动人心的跨学科研究方向。希格斯玻色子作为标准模型中最后被发现的基本粒子&#xff0c;其性质和行为对我们理解物质质量的起…

Elasticsearch:如何使用 Qwen3 来做向量搜索

在这篇文章中&#xff0c;我们将使用 Qwen3 来针对数据进行向量搜索。我们将对数据使用 qwen3 嵌入模型来进行向量化&#xff0c;并使用 Qwen3 来对它进行推理。在阅读这篇文章之前&#xff0c;请阅读之前的文章 “如何使用 Ollama 在本地设置并运行 Qwen3”。 安装 Elasticsea…

Mybatis实现页面增删改查

一、改变路由警告 二、实现新增数据 1.UserMapper.xml 2.Controller层 注意:前端传的是json对象,所以后台也需要使用JSON 3.设置提交的表单 <el-dialog title"信息" v-model"data.formVisible" width"30%" destroy-on-close><el-form…

Rabbitmq+STS+discovery_k8s +localpv部署排坑详解

#作者&#xff1a;朱雷 文章目录一、部署排坑1.1. configmap配置文件1.2. pv文件1.3. sc文件1.4. serviceAccount文件1.5. headless-service文件1.6. sts文件二、RabbitMQ集群部署关键问题总结一、部署排坑 1.1. configmap配置文件 编辑cm.yaml 文件 apiVersion: v1 kind: C…

8.14 模拟

lc658. deque 定长滑窗class Solution { public:vector<int> findClosestElements(vector<int>& arr, int k, int x) {int n arr.size();int l 0, r 0;deque<int> dq;while (r < n) {dq.push_back(arr[r]);if (dq.size() > k) {// 核心&#xf…