showliuzp 2025-09-17 21:30 采纳率: 84.3%
浏览 4
已结题

golang es条件查询


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 A struct {  
Createat    int  
ToUid       int  
Uid         int   
Content string
} 

这是要从es查询出来的字段



    userIndex := "lu_chat_log"
    termQuery := elastic.NewTermQuery("to_uid", req.StreamerId)

    searchResult, err := types.EsClient.Search().
        Index(userIndex).   // 设置索引名
        Query(termQuery).   // 设置查询条件
        Sort("create_at", true). // 设置排序字段,根据Created字段升序排序,第二个参数false表示逆序
        From(0). // 设置分页参数 - 起始偏移量,从第0行记录开始
        Size(10).   // 设置分页参数 - 每页大小
        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)
            }
        }

我有两个问题,第一个是除了uid和content能解析出来,剩下的create_at,to_uid都解析不出来

img

另外我想在elastic.NewTermQuery("to_uid", req.StreamerId)之外,在增加一个查询参数,elastic.NewTermQuery("uid", req.MemberId),该怎么做

  • 写回答

3条回答 默认 最新

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

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

    根据你提供的信息,你正在使用 Elasticsearch Go 客户端 进行查询,并且遇到了两个问题:


    一、字段无法解析的问题

    原因分析:

    你的结构体 A 的字段名与 Elasticsearch 中存储的字段名不一致。

    在你的数据中,字段名为:

    • create_at
    • to_uid
    • uid
    • content

    但你在 Go 结构体中定义为:

    type A struct {
        Createat int
        ToUid    int
        Uid      int
        Content  string
    }
    

    可以看到,Go 结构体中的字段名是 驼峰命名(Createat, ToUid, Uid),而 Elasticsearch 中的字段名是 下划线命名(create_at, to_uid, uid)

    Go 的 JSON 解析器默认会将结构体字段名与 JSON 字段名进行匹配,如果不一致,就无法正确解析。


    ✅ 解决方案:

    方法一:使用标签(Tag)映射字段名

    修改结构体定义,添加 JSON 标签来指定 Elasticsearch 中的实际字段名:

    type A struct {
        Createat int    `json:"create_at"`
        ToUid    int    `json:"to_uid"`
        Uid      int    `json:"uid"`
        Content  string `json:"content"`
    }
    

    重点: 使用 json:"字段名" 来映射 Elasticsearch 中的字段名。


    方法二:使用自定义反序列化(可选)

    如果你不想修改结构体,也可以通过自定义反序列化函数处理,但这种方式较为复杂,推荐第一种方式。


    二、如何添加多个 TermQuery 查询条件?

    你想在 elastic.NewTermQuery("to_uid", req.StreamerId) 的基础上,再添加一个 elastic.NewTermQuery("uid", req.MemberId),即同时查询 to_uid = req.StreamerIduid = req.MemberId


    ✅ 解决方案:

    使用 bool query 来组合多个条件。你可以使用 NewBoolQuery() 来构建一个逻辑“AND”关系的查询:

    // 构建 bool 查询
    boolQuery := elastic.NewBoolQuery()
    
    // 添加第一个条件:to_uid = req.StreamerId
    boolQuery = boolQuery.Must(
        elastic.NewTermQuery("to_uid", req.StreamerId),
    )
    
    // 添加第二个条件:uid = req.MemberId
    boolQuery = boolQuery.Must(
        elastic.NewTermQuery("uid", req.MemberId),
    )
    
    // 设置最终的查询
    termQuery := boolQuery
    
    // 然后继续执行搜索
    searchResult, err := types.EsClient.Search().
        Index(userIndex).
        Query(termQuery).
        Sort("create_at", true).
        From(0).
        Size(10).
        Pretty(true).
        Do(ctx)
    

    重点: 使用 elastic.NewBoolQuery().Must(...) 来组合多个 TermQuery,实现 AND 查询。


    三、完整代码示例(修改后的版本)

    type A struct {
        Createat int    `json:"create_at"`
        ToUid    int    `json:"to_uid"`
        Uid      int    `json:"uid"`
        Content  string `json:"content"`
    }
    
    userIndex := "lu_chat_log"
    
    // 构建 bool 查询
    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(userIndex).
        Query(boolQuery).
        Sort("create_at", true).
        From(0).
        Size(10).
        Pretty(true).
        Do(ctx)
    
    fmt.Printf("查询消耗时间 %d ms, 结果总数: %d\n", searchResult.TookInMillis, searchResult.TotalHits())
    
    if searchResult.TotalHits() > 0 {
        var b1 A
        for _, item := range searchResult.Each(reflect.TypeOf(b1)) {
            fmt.Printf("数据:%+v\n", item)
        }
    }
    

    四、总结

    1. 字段无法解析的原因及解决方法:

    | 问题 | 解决方法 | |------|----------| | 字段名不一致(Go 驼峰 vs Elasticsearch 下划线) | 在结构体中使用 json:"字段名" 标签映射 |

    2. 如何添加多个查询条件:

    | 问题 | 解决方法 | |------|----------| | 添加多个 TermQuery 条件 | 使用 elastic.NewBoolQuery().Must(...) 组合多个条件 |


    如需进一步优化性能或支持更复杂的查询逻辑(如 OR、范围等),可以继续使用 elastic 提供的其他查询类型,如 MatchQuery, RangeQuery, TermsQuery 等。

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

报告相同问题?

问题事件

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