showliuzp 2025-10-14 14:34 采纳率: 84.3%
浏览 2
已结题

golang写入es报错

//dao
package dao

import (
    "x_dream/types"
    "time"
    )

//记录操作日志到es
func OperatorAddEs(operator,module,act string,req interface{})(err error){
    data := map[string]interface{}{
        "operator"  : operator,
        "module"    : module,
        "act"       : act,
        "req"       : req,
        "dates"     : time.Now().Format(types.DATE_NORMAL_FORMAT),
    }

    _,err = types.EsClient.Index().Index(types.ES_OPERATOR_INDEX).BodyJson(data).Do(ctx)

    return
}

service:
func (o *Operator) OperatorAdd(r *http.Request,module,act string,req interface{})(err error){
    authorization := (*r).Header.Get(types.HEADER_AUTH)
    token_data,err := ParseToken(&authorization)
    if err != nil{
        err = response.NewErrCodeMsg(200, fmt.Sprintf("%v", err))
        return
    }

    admin_id    := token_data.AdminId
    admin_name  := token_data.UserName
    operator := fmt.Sprintf("admin_id:%d/admin_name:%s",admin_id,admin_name)

    err = dao.OperatorAddEs(operator,module,act,req)
    if err != nil {
        logx.Error(fmt.Sprintf("tags:operator_log,写入es异常,operator:%+v,req:%+v,err:%+v",operator,req,err))
    }

    return
}

//调用:
func LoginQuit(r *http.Request)(resp interface{},err error){
    authorization := (*r).Header.Get(types.HEADER_AUTH)
    if len(authorization) < 1{
                return nil, response.NewErrCodeMsg(200, "参数不正确")
    }

   authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmbGFnIjoiYWNjZXNzX3Rva2VuIiwiYWRtaW5faWQiOjIsImFjY291bnQiOiJhZG1pbiIsInVzZXJfbmFtZSI6ImFkbWluIiwiaXNzIjoibHVfbGl2ZSIsImV4cCI6MTc2MDQ2Mzc5N30.97e3r7RlCQ-f2W1Llv_Bc-0pTBDNtIe5j2QD0PlnvVA"

    if err = services.NewOperator().OperatorAdd(r,"login/quit","管理员退出",authorization);err != nil{
        return
    }


    err = services.NewLogin().Quit(&authorization)

    return
}

//我把数据写入到es里,但在写入的过程中,报错:elastic: Error 400 (Bad Request): [1:103] object mapping for [req] tried to parse field [req] as object, but found a concrete value [type=document_parsing_exception],现在可以确认是authorization的数据内容引起的,这是怎么回事?
  • 写回答

5条回答 默认 最新

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

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

    如果答案让您满意,请采纳、点赞、关注,非常感谢!
    .
    每日一句正能量,让它带给您好心情:你若盛开,清风自来;你若努力,幸运自会青睐。
    .

    根据你提供的代码和错误信息,这是一个Elasticsearch映射(mapping)冲突的问题。让我分析一下原因和解决方案:

    问题分析

    错误信息表明:

    • ES中已经存在对 req 字段的对象类型映射
    • 但你传入的 authorization 是一个字符串值(具体值)
    • ES尝试将字符串解析为对象时失败

    问题根源

    LoginQuit 函数中,你传递的 req 参数是:

    authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    

    这是一个JWT token字符串,但ES索引中 req 字段已经被映射为对象类型。

    解决方案

    方案1:统一数据结构(推荐)

    修改 OperatorAddEs 函数,确保 req 字段始终为对象:

    //dao
    func OperatorAddEs(operator, module, act string, req interface{}) (err error) {
        data := map[string]interface{}{
            "operator": operator,
            "module":   module,
            "act":      act,
            "req": map[string]interface{}{
                "data": req,  // 将原始数据包装在对象中
            },
            "dates": time.Now().Format(types.DATE_NORMAL_FORMAT),
        }
    
    
        _, err = types.EsClient.Index().Index(types.ES_OPERATOR_INDEX).BodyJson(data).Do(ctx)
        return
    }
    

    方案2:修改调用方式

    在调用时确保传递对象而非字符串:

    func LoginQuit(r *http.Request) (resp interface{}, err error) {
        authorization := (*r).Header.Get(types.HEADER_AUTH)
        if len(authorization) < 1 {
            return nil, response.NewErrCodeMsg(200, "参数不正确")
        }
    
    
        authorization = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
    
    
        // 将字符串包装为对象
        reqData := map[string]interface{}{
            "authorization": authorization,
        }
    
    
        if err = services.NewOperator().OperatorAdd(r, "login/quit", "管理员退出", reqData); err != nil {
            return
        }
    
    
        err = services.NewLogin().Quit(&authorization)
        return
    }
    

    方案3:重建ES索引(如果可行)

    如果ES中没有重要数据,可以删除并重建索引:

    # 删除现有索引
    curl -X DELETE "localhost:9200/你的索引名"
    
    
    # 创建带有正确映射的索引
    curl -X PUT "localhost:9200/你的索引名" -H 'Content-Type: application/json' -d'
    {
      "mappings": {
        "properties": {
          "req": {
            "type": "object"
          }
        }
      }
    }'
    

    建议

    1. 推荐使用方案1,因为它能保证数据结构的一致性
    2. 在ES中为 req 字段设置动态模板,允许不同类型的数据
    3. 考虑在写入ES前对数据进行类型检查和转换

    这样可以避免因数据类型不一致导致的映射冲突问题。

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

报告相同问题?

问题事件

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