在使用MongoDB将文档分配给Go中的结构之前,如何转换文档?

I am writing a multilingual API with go and mongodb. I have a mongo db document with format:

{
  _id : ObjectID(bla)
  "key" : {
    "en" : "Hello",
    "es" : "Hola"
  }
}

However, the API needs report json in the form:

{
  _id : ObjectID(bla),
  "key" : "Hola"
}

if the client sends language headers.

Is there an easy/efficent way to do this? The only working solution I have is to make two separate structs and then merge them together with a bunch of switch/case statements, like:

var api MyStruct
var mgo MyMgoStruct
session.DB("db").C("col").Find(nil).One(&mgo)

api.ID = mgo.ID
switch lang {
  default:
    {
      api.Key = string(mgo.Key.En)
    }
  case "es":
    {
      api.Key = string(mgo.Key.Es)
    }
}

Structure defs:

type Translation struct {
  En string `bson:"en"`
  Es string `bson:"es"`
}

type MyStruct struct {
  ID bson.ObjectID `json:"_id" bson:"_id"`
  Key string `json:"key" bson:"key"`
}

type MyMgoStruct struct {
  ID bson.ObjectID `json:"_id" bson:"_id"`
  Key Translation `json:"key" bson:"key"`
}

I foresee this becoming a huge pain to maintain, as my structures have tens of translated fields. I would prefer a way to transform the MongoDB document, replacing the Translation json structure with a simple key-value pair as in the MyStruct struct.

The only working solution I have is to make two separate structs and then merge them together with a bunch of switch/case statements

An alternative is you could use MongoDB projection on the Find(). Given your example document format, for example:

// Client input language header as variable
var languageInput = "es"  

// Concatenate to get field nest 'key'
key := "key." + languageInput 

// Only project the specific fields
cursor := coll.Find(nil).Select(bson.M{key: 1}) 

See also Project fields to return from query

If you have many translation fields in your struct that you don't want to map, you could utilise bson inline. For example:

type MyStruct struct {
    ID          bson.ObjectId      `json:"id" bson:"_id"`
    OtherFields bson.M             `bson:",inline"`
}

This would capture unstructured fields in OtherFields. See also bson.Marshal