英文:
How do I transform a document before I assign it to a structure in Go using MongoDB?
问题
我正在使用Go和MongoDB编写一个多语言API。我有一个MongoDB文档,格式如下:
{
_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)
}
}
结构体定义:
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文档,将Translation的JSON结构替换为MyStruct结构中的简单键值对。
英文:
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.
答案1
得分: 1
我唯一的有效解决方案是创建两个单独的结构体,然后使用一系列的switch/case语句将它们合并在一起。
另一种方法是使用MongoDB的投影功能在Find()方法上进行操作。以你的示例文档格式为例:
// 客户端输入的语言头部作为变量
var languageInput = "es"
// 拼接以获取嵌套字段 'key'
key := "key." + languageInput
// 仅投影特定字段
cursor := coll.Find(nil).Select(bson.M{key: 1})
参见 从查询结果中投影字段
如果你的结构体中有许多不想映射的翻译字段,你可以利用 bson inline
。例如:
type MyStruct struct {
ID bson.ObjectId json:"id" bson:"_id"
OtherFields bson.M bson:",inline"
}
这将捕获 OtherFields
中的非结构化字段。参见 bson.Marshal。
英文:
> 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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论