新项目必须用elastic/go-elasticsearch/v9,因olivere/elastic/v7已归档且不兼容es 8.0+,其未适配移除type、强制https、_search路径变更及content-type要求,导致406错误或静默失败;esapi.searchrequest须显式设置index、body(*bytes.reader)、context(带超时)。

新项目必须用 elastic/go-elasticsearch/v9,olivere/elastic/v7 已归档且连不上 ES 8.0+ ——不是代码问题,是协议断层:ES 移除了 _type、强制 HTTPS、改了 /_search 路径、要求 Content-Type: application/json,而 v7 完全没适配,一发请求就返回 406 Not Acceptable 或静默空响应。
esapi.SearchRequest 必须显式设 Index、Body 和 Context
esapi.SearchRequest 不补默认值,漏一个字段,ES 就当请求无效,返回空 hits 或 no search context found。
-
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 悬停
中文搜不到?先核对 analyzer 是否一致
写入时用了 ik_max_word 分词器,但查询没指定 "analyzer": "ik_max_word",ES 默认走 standard 分词器——“人工智能”被切成 “人工”“智能”,而 IK 会切出 “人工智能” 这个完整词项,自然匹配不上。
- 索引
mapping中对应字段必须明确定义"analyzer": "ik_max_word" - 查询 DSL 的
match或multi_match里必须加"analyzer": "ik_max_word"字段 - 别依赖“自动推断”,ES 不会跨字段猜 analyzer
查到结果但解析 panic?别直接 Unmarshal 到顶层结构体
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,大概率为空——ES 默认 1 秒才可搜索;title 字段 mapping 是 keyword,却用 match 查询,必然无结果,因为 keyword 不分词。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











