2017-08-17 116 views
0

在mgo中执行管道时使用bson名称。 结构:MGO返回bson字段而不是json字段

type Training struct { 
    Id     bson.ObjectId `json:"id" bson:"_id"` 
    Name    string   `json:"name" bson:"name"` 
    Description   string   `json:"description"` 
    Level    *TrainingLevel `json:"level"` 
    Preworks   []bson.ObjectId `json:"preworks"` 
    PrePostTests  []bson.ObjectId `json:"preposttests" bson:"preposttests"` 
    TrainingEvaluations []bson.ObjectId `json:"training_evaluations" bson:"training_evaluations"` 
    TrainerEvaluations []bson.ObjectId `json:"trainer_evaluations" bson:"trainer_evaluations"` 
    AppCompanyId  bson.ObjectId `json:"app_company_id" bson:"app_company_id"` 
    Company    *Company  `json:"company"` 
} 

功能:

func (this *TrainingClass) GetAllTraining() (interface{}, error) { 
    if !this.tokenInfo.IsAllowed(this.c) { 
     return nil, tlib.NewTError(common.Error_NoAccess, "You don't have the right!") 
    } 
    sess, db := GetDB() 
    defer sess.Close() 

    pipeline := []bson.M{ 
     {"$match": bson.M{ 
      "app_company_id": this.tokenInfo.AppCompanyId}}, 
     {"$lookup": bson.M{ 
      "from":   "trainingbatch", 
      "localField": "_id", 
      "foreignField": "training._id", 
      "as":   "trainingbatches"}}, 
    } 

    resp := []bson.M{} 
    db.C(common.C_TRAINING).Pipe(pipeline).All(&resp) 

    return bson.M{"data": resp}, nil 
} 

JSON结果:

{ 
    "data": [ 
    { 
     "_id": "5995a749dbcfbe4e8cc31378", 
     "app_company_id": "58b24756e65bd121f6b1a923", 
     "description": "Description First Training", 
     "name": "First Training", 
     "trainingbatches": [ 
     { 
      "_id": "5995a74adbcfbe4e8cc31379", 
      "app_company_id": "58b24756e65bd121f6b1a923", 
      "company": { 
      "_id": "58b24756e65bd121f6b1a923", 
      "address": "", 
      "app_company_id": "58b24756e65bd121f6b1a923", 
      "fullname": "", 
      "name": "Tandem", 
      "phone": "" 
      }, 
     } 
     ] 
    } 
    ] 
} 

正如你可以看到生成的,而不是id字段_id。如果我使用find或findId,则不会发生这种情况。无论查询是什么,是否有任何方法继续使用json字段?

回答

1

您读取结果的方式,它不知道JSON字段名称是什么。为了使用这些标签,它必须实际反序列化到标签已被指定的结构中。当您这样做时:

resp := []bson.M{} 
    db.C(common.C_TRAINING).Pipe(pipeline).All(&resp) 

您明确告诉mgo返回BSON结果。您传入的对象(bson.M的片段)上没有json标记。为了控制序列化到JSON,你必须通过一个结构与指定All的JSON标签:

resp := []Training 
    db.C(common.C_TRAINING).Pipe(pipeline).All(&resp) 
+0

但是,这将去掉'lookup'数据,不是吗? 如果我们需要为每个自定义连接('lookup')创建结构体,我认为在这个过程中会有点问题。或者,有没有处理这种东西的最佳做法? –

+0

如果您需要控制JSON字段名称,并且它们与BSON字段名称不匹配,则必须提供映射。这些映射最容易在结构标签中提供。这意味着您必须将结果反序列化为与结果结构匹配的结构。你可以使用匿名结构,但并不能节省很多,代码量大致相同。 – Adrian

+0

好的,谢谢阿德里安的回答。 –