使用_t定义查询C#驱动程序插入的记录

时间:2019-05-09 08:05:57

标签: mongodb go mongodb-query

我想查询由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
}

谢谢

2 个答案:

答案 0 :(得分:1)

您正在使用哪种mongo驱动程序? “ _t”是一个参数,如果当前类型不同于标称类型,则该参数用于确定要序列化的类型。它也用于普通的JSON序列化,因此您拥有我能想到的三种方式之一。

  1. 使用支持它的其他GO mongo驱动程序。我建议使用https://github.com/mongodb/mongo-go-driver,它是官方的MongoDB Go驱动程序
  2. 编写switch / case语句以自行反序列化
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. 您可以从mongo以JSON格式获取数据,并使用某些封送处理为您完成数据

答案 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字段并创建所选类型的“动态”实例。