content{"chat_text":"{\"type\":\"gift\",\"gift_id\":1,\"gift_title\":\"Santa Claus\",\"gift_gold\":10000,\"gift_count\":1,\"gift_icon\":\"/image/gift/santa_claus.png\"}"}create_at1,757,492,478id4-1757492476476-2-1266538ip171.243.49.200request_id113763315064409446status2to_uid6uaDart/3.9 (dart:io)uid4update_at1,757,492,478_idxqO3MpkB-4fCvSOnBrbW_ignored - _indexlu_chat_log_score1
这是es存储的数据结构
type Article struct {
Createat int `json:"create_at"`
ToUid int `json:"to_uid"`
Uid int `json:"uid"`
Content string `json:"content"`
}
这是要从es查询出来的字段
userIndex := "lu_chat_log"
boolQuery := elastic.NewBoolQuery()
boolQuery = boolQuery.Must(elastic.NewTermQuery("to_uid", req.StreamerId))
boolQuery = boolQuery.Must(elastic.NewTermQuery("uid", req.MemberId))
searchResult, err := types.EsClient.Search().
Index(types.LU_CHANT_INDEX).
Query(boolQuery).
Sort("create_at", true).
From(0). //第几页
Size(req.PageSize). //每页多少条
Pretty(true).//返回json
Do(ctx)
fmt.Printf("查询消耗时间 %d ms, 结果总数: %d\n", searchResult.TookInMillis, searchResult.TotalHits())
if searchResult.TotalHits() > 0 {
// 查询结果不为空,则遍历结果
var b1 A
// 通过Each方法,将es结果的json结构转换成struct对象
for _, item := range searchResult.Each(reflect.TypeOf(b1)) {
fmt.Printf("数据:%+v\n",item)
// 转换成Article对象
//if t, ok := item.(Article); ok {
//fmt.Println(t.Title)
}
}
boolQuery = boolQuery.Must(elastic.NewTermQuery("to_uid", req.StreamerId))
boolQuery = boolQuery.Must(elastic.NewTermQuery("uid", req.MemberId))
这个两个条件是and关系,现在我想再加一个or条件,条件类似这样的,(to_uid=10 and uid=11) or (to_uid=11 and uid=10),另外要加入分页
skip := (req.Page - 1) * req.PageSize
skip作为参数放入From函数
golang es or and查询
- 写回答
- 好问题 0 提建议
- 关注问题
- 邀请回答
-
3条回答 默认 最新
檀越@新空间 2025-09-17 22:17关注晚上好🌙🌙🌙
本答案参考通义千问根据你提供的信息,你的目标是使用 Elasticsearch (ES) 查询一个索引
lu_chat_log,并且实现如下查询逻辑:(to_uid = 10 and uid = 11) or (to_uid = 11 and uid = 10)
同时,你需要支持分页(通过
From和Size实现)。
✅ 重点说明
- 你当前的查询是两个
Must条件,表示 AND 关系。 - 现在要改成 OR 的关系,即两个条件组之间是 OR。
- 为了实现这个逻辑,需要使用
BoolQuery的Should子句,并结合MinimumShouldMatch设置为 1。 - 同时,分页逻辑需要将
skip作为From参数传入。
🧠 解决方案步骤
-
创建两个子查询条件:
- 第一个:
to_uid = 10且uid = 11 - 第二个:
to_uid = 11且uid = 10
- 第一个:
-
使用
Should子句将这两个条件组合成 OR 关系:- 使用
elastic.NewBoolQuery()创建一个boolQuery。 - 每个子条件使用
Must构建。 - 将两个子条件加入
Should中,并设置MinimumShouldMatch: 1。
- 使用
-
添加分页逻辑:
- 计算
skip = (req.Page - 1) * req.PageSize - 使用
From(skip)设置分页起始位置。
- 计算
-
执行查询并处理结果。
✅ 修改后的 Go 代码示例
// 定义用户请求参数结构体(假设) type Request struct { StreamerId int MemberId int Page int PageSize int } // 假设 req 是你的请求对象 userIndex := "lu_chat_log" boolQuery := elastic.NewBoolQuery() // 创建两个子查询条件 subQuery1 := elastic.NewBoolQuery(). Must(elastic.NewTermQuery("to_uid", 10)). Must(elastic.NewTermQuery("uid", 11)) subQuery2 := elastic.NewBoolQuery(). Must(elastic.NewTermQuery("to_uid", 11)). Must(elastic.NewTermQuery("uid", 10)) // 将两个子查询加入 Should 子句,并设置 MinimumShouldMatch: 1 boolQuery = boolQuery.Should(subQuery1, subQuery2).MinimumShouldMatch(1) // 分页逻辑 skip := (req.Page - 1) * req.PageSize // 执行搜索 searchResult, err := types.EsClient.Search(). Index(types.LU_CHANT_INDEX). Query(boolQuery). Sort("create_at", true). From(skip). // 分页起始位置 Size(req.PageSize). Pretty(true). Do(ctx) if err != nil { log.Fatal(err) } fmt.Printf("查询消耗时间 %d ms, 结果总数: %d\n", searchResult.TookInMillis, searchResult.TotalHits()) if searchResult.TotalHits() > 0 { var b1 Article for _, item := range searchResult.Each(reflect.TypeOf(b1)) { fmt.Printf("数据:%+v\n", item) // if t, ok := item.(Article); ok { // fmt.Println(t.Title) // } } }
🔍 其他建议
- 如果你有多个类似
(a AND b) OR (c AND d)的复杂查询,可以使用BoolQuery的Should+Must组合来构建。 - 注意字段类型:确保
to_uid和uid在 ES 中是keyword类型,否则TermQuery可能不生效。 - 性能优化:如果数据量很大,考虑使用
scroll API或增加size参数以避免深度分页问题。
📌 总结
| 步骤 | 内容 | |------|------| | 1 | 使用
BoolQuery构建两个子条件 | | 2 | 使用Should子句组合为 OR 关系 | | 3 | 添加MinimumShouldMatch: 1表示至少满足其中一个条件 | | 4 | 使用From和Size实现分页 | | 5 | 处理返回结果并转换为结构体 |如需进一步扩展或优化,请告诉我!
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报- 你当前的查询是两个