必须用elastic/go-elasticsearch/v8或v9,olivere/elastic/v7不兼容es 8.x+,因协议变更导致406错误或空响应;v7已归档,v8/v9为官方主线,支持api key、explain调试等新特性。

用哪个客户端?v8/v9 还是 olivere/elastic/v7
必须用 elastic/go-elasticsearch/v8 或 v9,olivere/elastic/v7 在 ES 8.0+ 上根本连不上——不是报错,而是发请求后返回 406 Not Acceptable 或空响应。ES 8.x 移除了 _type、强制 HTTPS、改了 /_search 路径、要求 Content-Type: application/json,而 v7 完全没适配这些变更。v7 已归档,不再接收任何 PR 或安全更新;v8 和 v9 是官方主线,持续支持 API key、explain 调试、searchable snapshot 等新特性。
esapi.SearchRequest 必须填哪三个字段
官方客户端不补默认值,漏一个就等于发了个废请求,结果常是空 hits 或 no search context found:
-
Index:不能为""或"*";生产环境 ES 会拒收或打满慢日志;必须明确传[]string{"blogs"} -
Body:必须是*bytes.Reader;常见错误是json.Marshal()后忘了包一层bytes.NewReader(),导致请求体为空,ES 返回400 Bad Request -
Context:必须带超时,例如context.WithTimeout(ctx, 5*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, &myDoc)
注意:如果创建索引时设置了 "_source": false,hit.Source 就是 nil,必须提前确认 mapping 配置;聚合结果也类似,aggregations 是嵌套 map,字段名必须和返回 key 完全一致(如 doc_count 不是 count),建议用 searchResponse.Aggregations 方法而非手动取 map。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











