showliuzp 2025-10-24 21:50 采纳率: 84.3%
浏览 5
已结题

golang es where条件更新日期疑问



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

更新代码:
func (ws *WsChat) WsChatUpdateMsgSeen(uid,to_uid int64){
    //查询条件
    query := elastic.NewBoolQuery().
        Must(elastic.NewTermQuery("uid", uid)).
        Must(elastic.NewTermQuery("to_uid", to_uid)).
        Must(elastic.NewRangeQuery("create_at").Lt(time.Now().Unix()))

    script := elastic.NewScript("ctx._source.status = 1")
    _, err := types.EsClient.UpdateByQuery(types.LU_CHANT_INDEX).
        Query(query).
        Script(script).
        Refresh("true"). // 立即刷新使更改可见
        Do(ctx)
    if err != nil {
        fmt.Errorf("更新失败: %v", err)
    }
}

我通过uid、to_uid、create_at来更新语句,只要不加create_at条件就可以更新成功,es里create_at的摸样在图片里,我粘贴出来:create_at    1,760,343,276,莫非格式不是时间戳类型,导致的,但create_at的更新他条件值是时间戳类型
  • 写回答

3条回答 默认 最新

  • 宝码香车 优质创作者: JavaScript技术领域 2025-10-24 22:04
    关注

    让【宝码香车】来帮您解答,本回答参考DeepSeek编写,并整理提供。

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:生活或许有遗憾,但未来仍有可期。
    .

    根据您提供的信息和代码,问题很可能出现在 create_at 字段的数据类型上。从您提供的截图来看,create_at 字段的值显示为 1,760,343,276,这看起来是一个长整型数值(Unix 时间戳),但 Elasticsearch 中的字段类型可能不是数值类型。

    问题分析

    1. 字段类型不匹配:如果 create_at 在 Elasticsearch 映射中被定义为 text 类型而不是 longdate 类型,那么使用数值范围查询就会失败。
    1. 逗号分隔问题:显示中的逗号 1,760,343,276 可能是格式化显示,实际存储的应该是 1760343276

    解决方案

    方案1:检查字段映射

    首先确认 create_at 字段的映射类型:

    // 获取索引映射
    resp, err := types.EsClient.GetMapping().
        Index(types.LU_CHANT_INDEX).
        Do(ctx)
    if err != nil {
        fmt.Errorf("获取映射失败: %v", err)
    }
    
    
    // 打印映射信息查看 create_at 字段类型
    fmt.Printf("映射信息: %+v\n", resp)
    

    方案2:修改查询条件

    如果 create_at 是文本类型,需要将时间戳转换为字符串查询:

    func (ws *WsChat) WsChatUpdateMsgSeen(uid, to_uid int64) {
        currentTime := time.Now().Unix()
        
        // 如果 create_at 是文本类型
        query := elastic.NewBoolQuery().
            Must(elastic.NewTermQuery("uid", uid)).
            Must(elastic.NewTermQuery("to_uid", to_uid)).
            Must(elastic.NewRangeQuery("create_at").Lt(fmt.Sprintf("%d", currentTime)))
    
    
        // 或者尝试使用脚本进行类型转换比较
        script := elastic.NewScript(`
            if (Long.parseLong(ctx._source.create_at) < params.current_time) {
                ctx._source.status = 1
            }
        `).Param("current_time", currentTime)
    
    
        _, err := types.EsClient.UpdateByQuery(types.LU_CHANT_INDEX).
            Query(query).
            Script(script).
            Refresh("true").
            Do(ctx)
        if err != nil {
            fmt.Errorf("更新失败: %v", err)
        }
    }
    

    方案3:使用脚本处理类型转换

    更安全的方式是在脚本中处理类型转换:

    func (ws *WsChat) WsChatUpdateMsgSeen(uid, to_uid int64) {
        query := elastic.NewBoolQuery().
            Must(elastic.NewTermQuery("uid", uid)).
            Must(elastic.NewTermQuery("to_uid", to_uid))
    
    
        scriptStr := `
            def createAt = ctx._source.create_at;
            // 处理可能的字符串类型
            if (createAt instanceof String) {
                createAt = Long.parseLong(createAt);
            }
            if (createAt < params.current_time) {
                ctx._source.status = 1;
            }
        `
    
    
        script := elastic.NewScript(scriptStr).
            Param("current_time", time.Now().Unix())
    
    
        _, err := types.EsClient.UpdateByQuery(types.LU_CHANT_INDEX).
            Query(query).
            Script(script).
            Refresh("true").
            Do(ctx)
        if err != nil {
            fmt.Errorf("更新失败: %v", err)
        }
    }
    

    方案4:修复数据映射(推荐长期方案)

    如果确认应该是数值类型,建议修改映射:

    {
      "mappings": {
        "properties": {
          "create_at": {
            "type": "long"
          }
        }
      }
    }
    

    调试建议

    1. 单独测试查询:先使用相同的查询条件执行搜索,确认是否能返回预期文档:
    searchResult, err := types.EsClient.Search().
        Index(types.LU_CHANT_INDEX).
        Query(query).
        Size(10).
        Do(ctx)
    
    1. 检查错误信息:获取更详细的错误信息:
    if err != nil {
        if elasticErr, ok := err.(*elastic.Error); ok {
            fmt.Printf("Elasticsearch错误详情: %s\n", elasticErr.Details)
        }
        fmt.Errorf("更新失败: %v", err)
    }
    

    建议先使用方案1检查字段映射类型,然后根据实际类型选择合适的解决方案。

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

报告相同问题?

问题事件

  • 系统已结题 11月2日
  • 已采纳回答 10月25日
  • 创建了问题 10月24日