【问题标题】:MongoDB returns object data as array of key-value pair in GoMongoDB 在 Go 中将对象数据作为键值对数组返回
【发布时间】:2021-10-23 20:56:49
【问题描述】:

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

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

Data的结构是:

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

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

【问题讨论】:

    标签: mongodb go aggregation


    【解决方案1】:

    试试这个

    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{} 的负担由库来找出类型是什么。如果您希望地图中有不同的值,您可以使用map[string]interface{}

    【讨论】:

    • 数据甚至可以包含数组、字符串或任何其他类型。这就是为什么我保留它的界面。
    【解决方案2】:

    为这个问题找到了一个非常奇怪的解决方案,我将其解码为 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
            }
    }
    

    【讨论】:

      猜你喜欢
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 2018-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多