MGO返回bson字段而不是json字段。

huangapple go评论95阅读模式
英文:

MGO return bson field instead of json field

问题

bson名称在mgo中执行管道时使用。
结构体:

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字段?

英文:

The bson name is used when performing pipe in mgo.
Struct :

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"`
}

Function :

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 result :

{
  "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": ""
          },
        }
      ]
    }
  ]
}

As you can see field _id is generated instead of id. That's not happen if I use find or findId. Is there any way to keep using json field no matter what's the query?

答案1

得分: 2

你阅读结果的方式,它并不知道 JSON 字段的名称。为了让它使用这些标签,必须将其反序列化为已指定标签的结构体中。当你这样做时:

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

你明确告诉 mgo 返回 BSON 结果。你传入的对象(bson.M 切片)上没有 JSON 标签。为了控制序列化为 JSON,你必须传入一个带有指定 JSON 标签的结构体给 All

resp := []Training{}
db.C(common.C_TRAINING).Pipe(pipeline).All(&resp)
英文:

The way you're reading the result, it has no idea what the JSON field names are. In order for it to use those tags, it must actually deserialize into the struct where the tags have been specified. When you do:

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

You're explicitly telling mgo to return BSON results. The object you pass in (a slice of bson.M) has no json tags on it. In order to control the serialization to JSON, you must pass a struct with the JSON tags specified to All:

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

huangapple
  • 本文由 发表于 2017年8月17日 23:22:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/45739102.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定