showliuzp 2025-09-17 22:16 采纳率: 84.3%
浏览 2
已结题

golang es or and查询


 
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函数
  • 写回答

3条回答 默认 最新

  • 檀越@新空间 2025-09-17 22:17
    关注

    晚上好🌙🌙🌙
    本答案参考通义千问

    根据你提供的信息,你的目标是使用 Elasticsearch (ES) 查询一个索引 lu_chat_log,并且实现如下查询逻辑:

    (to_uid = 10 and uid = 11) or (to_uid = 11 and uid = 10)

    同时,你需要支持分页(通过 FromSize 实现)。


    ✅ 重点说明

    • 你当前的查询是两个 Must 条件,表示 AND 关系。
    • 现在要改成 OR 的关系,即两个条件组之间是 OR
    • 为了实现这个逻辑,需要使用 BoolQueryShould 子句,并结合 MinimumShouldMatch 设置为 1。
    • 同时,分页逻辑需要将 skip 作为 From 参数传入

    🧠 解决方案步骤

    1. 创建两个子查询条件

      • 第一个:to_uid = 10uid = 11
      • 第二个:to_uid = 11uid = 10
    2. 使用 Should 子句将这两个条件组合成 OR 关系

      • 使用 elastic.NewBoolQuery() 创建一个 boolQuery
      • 每个子条件使用 Must 构建。
      • 将两个子条件加入 Should 中,并设置 MinimumShouldMatch: 1
    3. 添加分页逻辑

      • 计算 skip = (req.Page - 1) * req.PageSize
      • 使用 From(skip) 设置分页起始位置。
    4. 执行查询并处理结果


    ✅ 修改后的 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) 的复杂查询,可以使用 BoolQueryShould + Must 组合来构建。
    • 注意字段类型:确保 to_uiduid 在 ES 中是 keyword 类型,否则 TermQuery 可能不生效。
    • 性能优化:如果数据量很大,考虑使用 scroll API 或增加 size 参数以避免深度分页问题。

    📌 总结

    | 步骤 | 内容 | |------|------| | 1 | 使用 BoolQuery 构建两个子条件 | | 2 | 使用 Should 子句组合为 OR 关系 | | 3 | 添加 MinimumShouldMatch: 1 表示至少满足其中一个条件 | | 4 | 使用 FromSize 实现分页 | | 5 | 处理返回结果并转换为结构体 |

    如需进一步扩展或优化,请告诉我!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 9月26日
  • 已采纳回答 9月18日
  • 创建了问题 9月17日