必须用elastic/go-elasticsearch/v9,因olivere/elastic/v7未适配es 8.0+协议变更(移除_type、强制https、_search路径调整、content-type要求),导致400/406错误或静默失败;esapi.searchrequest须显式设置index、body(*bytes.reader)、context(带超时)。

必须用 elastic/go-elasticsearch/v9,olivere/elastic/v7 在 ES 8.0+ 上根本连不上——不是代码写错了,是协议断层导致 400/406 静默失败。
选错客户端版本:连请求都发不出去
ES 8.0+ 移除了 _type、强制 HTTPS、变更了 /_search 路径、要求 Content-Type: application/json,而 olivere/elastic/v7 完全没适配这些。现象是:req.Do() 返回空 hits 或直接 406 Not Acceptable,错误日志里看不到真实原因。
- ES 7.10–7.17 → 可用
olivere/elastic/v7(仅限存量迁移) - ES 8.0+(包括刚装的 8.15 / 9.0)→ 必须用
elastic/go-elasticsearch/v9 - 同一项目混用两个客户端 →
context.Context传参冲突、http.RoundTripper复用异常,可能静默超时
esapi.SearchRequest 必须显式设三个字段
官方客户端不补默认值,漏一个就等于发了个废请求:返回空结果、no search context found 或 panic。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
-
Index:不能为""或"*";生产环境禁止通配符,ES 可能拒收或打满慢日志;必须明确传[]string{"blogs"} -
Body:必须是*bytes.Reader;常见错误是json.Marshal()后忘了包一层bytes.NewReader(),导致请求体为空,ES 返回400 Bad Request -
Context:必须带超时,例如context.WithTimeout(ctx, 3*time.Second);不设的话 HTTP client 可能卡死在连接池,goroutine 悬停
中文搜不到?先盯住分词器、refresh 和字段类型
90% 的“搜不到”不是 query 写错,而是索引侧配置和写入行为不一致。
- 中文分词:索引用了
ik_max_word,但查询 DSL 没加"analyzer": "ik_max_word",ES 默认走standard分词器——“人工智能”被切成 “人工”“智能”,而 IK 会切出完整词项,自然匹配不上 -
refresh延迟:文档写入后默认 1 秒才可搜索;刚Index()完立刻Search(),大概率为空;开发期可临时加Refresh: "true",但批量导入时严禁使用 - 字段类型错配:
title字段 mapping 是keyword,却用MatchQuery查——keyword不分词,MatchQuery查不了;该用TermQuery
解析 hit.Source 时最容易 panic
ES 返回的文档内容在 hit._source 下,不是 JSON 根对象。直接 json.Unmarshal(raw, &MyDoc{}) 会失败或字段为空。
- 正确做法是调
hit.Source方法:err := json.Unmarshal(*hit.Source, &doc),注意*hit.Source是指针 - 别手动取嵌套
map解析聚合结果;用searchResponse.Aggregations方法(v9 客户端提供),它已处理 key 映射和类型转换 - 字段名必须和 mapping 完全一致:
user_id≠userId,查不到不会报错,只会返回空 slice
最易被忽略的是 refresh 延迟和字段类型错配:刚 Index 完立刻 Search,大概率为空;title 字段 mapping 是 keyword,却用 match 查询,必然无结果。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










