MongoDB在Go语言中以键值对数组的形式返回对象数据

5kgi1eie  于 2022-11-22  发布在  Go
关注(0)|答案(3)|浏览(101)

我写了下面的查询,它返回我的记录,其中updated_at日期大于synced_at日期从所有记录使用mongodb库在Golang。

pipeline := []bson.M{}
    filter := []string{"$updated_at", "$synced_at"}
    pipeline = append(pipeline, bson.M{"$match": bson.M{"$expr": bson.M{"$gte": filter}}})
    opts := options.Aggregate().SetMaxTime(2 * time.Second)
    cursor, err := collection.Aggregate(ctx, pipeline, opts)
    for cursor.Next(context.Background()) {
        records := model.DData{}
        err = cursor.Decode(&records)
    }

数据结构为:

type DData struct {
    Name               string       `json:"name" bson:"name"` 
    Data               interface{}  `json:"data" bson:"data"`
    UpdatedAt          time.Time    `json:"updated_at" bson:"updated_at"`
    SyncedAt           time.Time     `json:"synced_at" bson:"synced_at"`
}

收集的数据格式为:

{
    "name":"Vallabh",
    "data":{
        "field1":"value1",
        "field2":"value2",
        "field3":"value3",
    },
    "updated_at":2021-08-17T09:43:27Z,
    "synced_at":2021-08-07T09:43:27Z
}

但使用上面的查询,我得到的数据格式为:

{
    "name":"Vallabh",
    "data":[
        {
            "key":"field1",
            "value":"value1"
        },
        {
            "key":"field2",
            "value":"value2"
        },
        {
            "key":"field3",
            "value":"value3"
        }
    }],
    "updated_at":"2021-08-17T09:43:27Z",
    "synced_at":"2021-08-07T09:43:27Z"
}

我做错了什么?只有当字段类型是结构体中的接口时才会发生。

xtupzzrd

xtupzzrd1#

试试这个

type DData struct {
    Name               string             `json:"name" bson:"name"` 
    Data               map[string]string  `json:"data" bson:"data"`
    UpdatedAt          time.Time          `json:"updated_at" bson:"updated_at"`
    SyncedAt           time.Time          `json:"synced_at" bson:"synced_at"`
}

如果你事先知道类型,就一定要使用它,对于interface{},库需要找出类型。

56lgkhnf

56lgkhnf2#

找到了一个非常奇怪的解决这个问题的方法,我把它解码成bson.M{},然后把它编组和解组到我的结构体中。我相信有更好的方法,但这一个对我很有效。

for cursor.Next(context.Background()) {
        tempResult := bson.M{}
        err = decode(cursor, &tempResult)
        if err != nil {
            logger.LogErrorf(err, "error while decoding")
            continue
        }
        obj, err := marshal(tempResult)
        if err != nil {
            logger.LogErrorf(err, "error while marshalling")
            continue
        }
        var data model.DData
        err = json.Unmarshal(obj, &data)
        if err != nil {
            tenant.LogError(err, "error while marshalling")
            continue
        }
}
jrcvhitl

jrcvhitl3#

@VallabhLakade我也有类似的担忧,尝试了下面的方法,帮助.
基本上问题是mongo-driver默认解组为bson.D,对于interface{}类型的结构体,mgo-driver默认解组为bson.M
因此,在尝试与mongo-dbSetRegistry()选项建立连接时,我们必须添加以下代码作为clientOpts。要Map旧的mgo行为,以便在解组interface{}类型的结构时,mongo-driver默认为bson.M,并且这不应将值显示回key-value

tM := reflect.TypeOf(bson.M{})
    reg := bson.NewRegistryBuilder().RegisterTypeMapEntry(bsontype.EmbeddedDocument, tM).Build()
    clientOpts := options.Client().ApplyURI(SOMEURI).SetAuth(authVal).SetRegistry(reg)
    client, err := mongo.Connect(ctx, clientOpts)

引用-〉MongoDB文档返回go mongo-driver中键值对的数组

相关问题