我想查询由C#mongodriver插入的具有多态性的数据。该查询将由Golang驱动程序完成。数据的结构如下所示。我想将_t映射到结构,换句话说,我想应用多态性在Go中进行记录。在Golang mongo驱动程序中可以做到吗?结构列表也在下面。
mongo集合中的一个记录示例
{"_id" : "asdasda12312312asdasda",
"structure" : [
{
"_t" : "AObject",
"Text" : "asdasdasda",
"State" : "asdasda"
},
{
"_t" : "BObject",
"Number" : "123",
},
{
"_t" : "CObject",
"Testing" : "Pompeo"
}
]
}
去结构
type Data struct{
_id string
Structure []Object
}
type Object interface{
}
type AObject struct {
Text string
State string
}
type BObject struct {
Number string
}
type CObject struct {
Testing string
}
谢谢
答案 0 :(得分:1)
您正在使用哪种mongo驱动程序? “ _t”是一个参数,如果当前类型不同于标称类型,则该参数用于确定要序列化的类型。它也用于普通的JSON序列化,因此您拥有我能想到的三种方式之一。
type MongoObject struct {
// Contains all fields from all objects
_t string
Text string
State string
Number string
Testing string
}
func DeserializeObject(object MongoObject) Object{
switch t {
case "AObject":
return &AObject{Text: object.Text, State: object.State}
case "BObject":
return &BObject{Number: object.Text}
case "CObject":
return &CObject{Testing: object.Testing}
}
}
答案 1 :(得分:0)
使用接口通常是有问题的,因为进行解组的库将很难决定选择哪种类型。您可以使用自定义拆组器来选择适当的类型,但这更加麻烦和复杂。
最简单的方法是使用具体的结构类型。您必须使用struct tags在struct字段和MongoDB文档中的字段之间进行映射。重要的一点是,在Go字段中必须导出字段,否则执行工作的库无法填充/读取字段。为了将其导出,其名称必须以大写字母开头,并且下划线(_
)不是其中之一。
如果(子)文档可能基于值具有不同的字段,则可以添加所有字段,并且存在的文档将正确地编组。
您的文档可以这样建模:
type Data struct {
ID string `bson:"_id"`
Structure []Object `bson:"structure"`
}
type Object struct {
T string `bson:"_t"`
Text string `bson:"Text,omitempty"`
State string `bson:"State,omitempty"`
Number string `bson:"Number,omitempty"`
Testing string `bson:"Testing,omitempty"`
}
请注意,,omitempty
选项对于拆组不是必需的,但是如果您想使用这些相同的类型进行编组(例如保存新文档),则,omitempty
选项将确保留空字段。
还请注意,如果这不满足您的要求,则不会阻止您对结果进行后处理。您可以打开可用的Object.T
字段并创建所选类型的“动态”实例。