showliuzp 2025-10-14 15:46 采纳率: 84.3%
浏览 3
已结题

golang es分页查询


//es存储的数据结构
act登录成功dates2025-10-14 15:04:57modulelogin/checkoperatoradminreq.data{"UserName":"admin","Password":"123456"}

![img](https://i-blog.csdnimg.cn/ask/2a24fbe3d8c143079628a7f3c8ff75a6.png "#left")

我写了如下的分页:
    skip := (req.Page - 1) * req.PageSize

    searchResult, err := types.EsClient.Search().
        Index(types.ES_OPERATOR_INDEX).
        Sort("create_at", true).
        From(skip). //第几页
        Size((*req).PageSize).   //每页多少条
        Pretty(true).//返回json
        Do(ctx)


    //fmt.Printf("查询消耗时间 %d ms, 结果总数: %d\n", searchResult.TookInMillis, searchResult.TotalHits())

    if searchResult.TotalHits() < 1{
        resp.List = make([]iapi.OperatorList,0)
        return
    }

  
}

我想把截图里的act、module、operator、req.data,dates都分页遍历出来,应该怎么做
  • 写回答

5条回答 默认 最新

  • 檀越@新空间 2025-10-14 15:47
    关注

    下午好🌅🌅🌅
    本答案参考通义千问

    根据你提供的信息,你正在使用 Go 语言(Golang)与 Elasticsearch(ES) 进行交互,并尝试实现分页查询。你提到的字段如 actmoduleoperatorreq.datadates 都是存储在 ES 中的数据结构的一部分。

    为了实现对这些字段的分页遍历,你需要做以下几个步骤:


    1. 确保数据结构正确映射到 Elasticsearch

    在使用 Elasticsearch 进行查询前,必须确保你的数据结构已经被正确地索引和映射。例如,假设你的文档结构如下:

    {
      "act": "login",
      "module": "check",
      "operator": "admin",
      "req": {
        "data": {
          "UserName": "admin",
          "Password": "123456"
        }
      },
      "dates": "2025-10-14T15:04:57Z"
    }
    

    你需要确认该结构在 Elasticsearch 中已经创建了合适的 mapping。如果尚未创建,可以使用以下方式定义 mapping:

    // 定义 mapping
    mapping := map[string]interface{}{
    	"mappings": map[string]interface{}{
    		"properties": map[string]interface{}{
    			"act":           {"type": "text"},
    			"module":        {"type": "text"},
    			"operator":      {"type": "text"},
    			"req": map[string]interface{}{
    				"properties": map[string]interface{}{
    					"data": map[string]interface{}{
    						"properties": map[string]interface{}{
    							"UserName": {"type": "text"},
    							"Password": {"type": "text"},
    						},
    					},
    				},
    			},
    			"dates": {"type": "date"},
    		},
    	},
    }
    
    // 创建索引并设置 mapping
    _, err := types.EsClient.Indices.Create(types.ES_OPERATOR_INDEX, types.EsClient.Indices.Create.WithBody(
    	json.NewEncoder(buf).Encode(mapping),
    ))
    

    2. 实现分页查询逻辑

    你目前的分页逻辑基本正确,但需要补充一些细节,比如如何解析返回结果中的字段。以下是优化后的分页查询代码示例:

    分页查询代码示例:

    skip := (req.Page - 1) * req.PageSize
    
    searchResult, err := types.EsClient.Search().
        Index(types.ES_OPERATOR_INDEX).
        Sort("dates", true). // 按日期排序,升序
        From(skip).
        Size(req.PageSize).
        Pretty(true).
        Do(ctx)
    
    if err != nil {
        return nil, err
    }
    
    // 获取总结果数
    totalHits := searchResult.TotalHits()
    if totalHits < 1 {
        return make([]iapi.OperatorList, 0), nil
    }
    
    // 解析结果
    var results []iapi.OperatorList
    for _, hit := range searchResult.Hits.Hits {
        var op iapi.OperatorList
        if err := json.Unmarshal(hit.Source, &op); err != nil {
            return nil, err
        }
        results = append(results, op)
    }
    
    return results, nil
    

    3. 提取所需字段(act、module、operator、req.data、dates)

    如果你只需要提取某些特定字段,可以在查询时指定 _source 参数来限制返回内容:

    修改后的查询代码:

    searchResult, err := types.EsClient.Search().
        Index(types.ES_OPERATOR_INDEX).
        Sort("dates", true).
        From(skip).
        Size(req.PageSize).
        SourceFilter(&elastic.SourceFilter{
            Includes: []string{"act", "module", "operator", "req.data", "dates"},
        }).
        Pretty(true).
        Do(ctx)
    

    注意: 如果 req.data 是嵌套对象,你可以用 req.data.UserNamereq.data.Password 来精确提取子字段。


    4. 处理嵌套字段(如 req.data)

    如果你希望从 req.data 中提取 UserNamePassword,可以这样处理:

    var op iapi.OperatorList
    err := json.Unmarshal(hit.Source, &op)
    if err != nil {
        return nil, err
    }
    
    fmt.Printf("User: %s, Password: %s\n", op.Req.Data.UserName, op.Req.Data.Password)
    

    5. 分页遍历所有数据(多页查询)

    如果你想遍历所有页面,可以使用循环进行分页:

    多页遍历代码示例:

    var allResults []iapi.OperatorList
    page := 1
    pageSize := 100
    total := 0
    
    for {
        skip := (page - 1) * pageSize
        searchResult, err := types.EsClient.Search().
            Index(types.ES_OPERATOR_INDEX).
            Sort("dates", true).
            From(skip).
            Size(pageSize).
            SourceFilter(&elastic.SourceFilter{
                Includes: []string{"act", "module", "operator", "req.data", "dates"},
            }).
            Do(ctx)
    
        if err != nil {
            break
        }
    
        total = int(searchResult.TotalHits())
        if total == 0 {
            break
        }
    
        for _, hit := range searchResult.Hits.Hits {
            var op iapi.OperatorList
            if err := json.Unmarshal(hit.Source, &op); err != nil {
                continue
            }
            allResults = append(allResults, op)
        }
    
        page++
    }
    

    总结:关键步骤一览

    1. 确认数据结构已正确映射到 Elasticsearch
    2. 使用 Sort, From, Size 实现分页
    3. 通过 SourceFilter 限制返回字段
    4. 解析 JSON 结果并提取所需字段
    5. 遍历所有页面获取全部数据

    最终建议

    • 使用 Elasticsearch 的 Scroll API 可以更高效地遍历大数据集。
    • 如果你只是想“分页遍历”,当前方法已经足够。
    • 如果性能要求高,考虑使用 Scroll APISearch After 替代方案。

    如有更多关于字段结构或查询条件的问题,欢迎继续提问!

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

报告相同问题?

问题事件

  • 系统已结题 10月22日
  • 已采纳回答 10月14日
  • 创建了问题 10月14日