es默认standard分词器对中文单字切分,需安装ik插件、在mapping中为字段指定analyzer和search_analyzer,并用match查询,否则中文检索失败。

直接用 Gin 调 Elasticsearch(ES)做中文分词检索,核心难点不在 Gin,而在 ES 本身——默认分词器对中文无效,不装 ik 或 smartcn 插件,搜“苹果手机”会拆成“苹”“果”“手”“机”,结果全错。
为什么 Gin 里调 ES 总是搜不出中文?
因为 ES 默认的 standard 分词器按 Unicode 字符切分,对中文就是单字切分。Gin 只是发 HTTP 请求,真正分词逻辑在 ES 侧。你看到的“搜不到”“命中率低”“返回空”,90% 是分词配置没生效。
- 检查集群是否已安装
ik插件:GET /_cat/plugins?v,输出里要有ik - 确认索引创建时指定了
analyzer:"analyzer": "ik_max_word",不是"analyzer": "standard" - Gin 发的请求体里,
query部分必须用match或multi_match,别用term(它不分词)
Gin 中调 ES 的最小可行请求结构
不要封装太重,先确保能跑通基础查询。Gin handler 里用 http.Client 发 raw JSON 即可,重点是 body 结构和 header。
- URL:
http://localhost:9200/your_index/_search - Header 必须带:
Content-Type: application/json - Body 示例(中文全文匹配):
{
"query": {
"match": {
"title": "苹果手机"
}
},
"analyzer": "ik_max_word"
}
注意:analyzer 放 query 外层是无效的;必须在 mapping 里定义字段的 analyzer,或用 match 的 analyzer 参数(仅限该 query 临时覆盖)。
mapping 里不配 ik,一切白搭
就算插件装了、请求写对了,如果索引 mapping 没把字段声明为用 ik 分词,ES 依然走默认分词。建索引时必须显式指定:
PUT /product_index
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
}
}
}
-
analyzer用于索引时分词(写入) -
search_analyzer用于查询时分词(读取),ik_smart更精准,适合搜索场景 - 已有索引不能直接改 analyzer,得 reindex 或删重建
Gin + ES 中文检索容易漏掉的三件事
不是代码写错,而是环境、配置、数据流三个环节卡住:
- ES 启动后没等
green状态就往里写数据 —— 查GET /_cat/health?v,必须是green - 用
POST /product_index/_doc写入文档时,没带中文内容(比如字段名拼错、JSON 格式非法导致字段被忽略) - Gin 接收前端参数后,没做 trim 或空值判断,传了空字符串给 ES,
match查询直接返回空结果
真正难的从来不是 Gin 怎么写,而是确认 ES 那边的分词器真正在工作——POST /product_index/_analyze?analyzer=ik_max_word 手动测一下输入“苹果手机”输出是不是 [苹果, 手机],这步跳过,后面全是徒劳。











