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

时间:2017-06-09 07:49:16

标签: json mongodb go internationalization bson

我正在使用go和mongodb编写多语言API。我有一个mongo db文档,格式为:

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

但是,API需要以以下形式报告json:

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

如果客户端发送语言标题。

有一种简单/有效的方法吗?我唯一可行的解​​决方案是创建两个单独的结构,然后将它们与一堆switch / case语句合并在一起,例如:

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)
    }
}

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

我预见这将成为一个巨大的痛苦,因为我的结构有数十个翻译领域。我更喜欢一种转换MongoDB文档的方法,用MyStruct结构中的简单键值对替换Translation json结构。

1 个答案:

答案 0 :(得分:1)

  

我唯一可行的解​​决方案是创建两个单独的结构,然后将它们与一堆switch / case语句合并在一起

另一种方法是你可以在Find()上使用MongoDB投影。给出您的示例文档格式,例如:

// 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}) 

另见Project fields to return from query

如果您的结构中有许多您不想映射的翻译字段,则可以使用bson inline。例如:

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

这将捕获OtherFields中的非结构化字段。另请参阅bson.Marshal