【问题标题】:Go-MongoDriver decoding JSON array weirdlyGo-MongoDriver 奇怪地解码 JSON 数组
【发布时间】:2021-07-11 12:58:13
【问题描述】:

嗨,派对的人,

我最近开始学习 Go,并开始从事一个小型项目,其中包括使用 Go Fiber 库编写的 API。 所有必需的数据都使用以下模式存储在 MongoDB 中

{
    "ObjectId": {
        "name": "name",
        "url": "url",
        "dateAdded": "date",
        "data": [{
                "timestamp 1": "price 1"
            },
            {
                "timestamp 2": "price 2"
            }
        ]
    }
}

项目类型如下所示:

type Item struct {
    ID        primitive.ObjectID `json:"_id" bson:"_id"`
    Name      string             `json:"name" bson:"name"`
    URL       string             `json:"url" bson:"url"`
    DateAdded string             `json:"dateAdded" bson:"dateAdded"`
    Data      []interface{}      `json:"data" bson:"data"`
}

每当我使用

查询存储的项目时
err = collection.FindOne(context.TODO(), filter).Decode(&item)

数据数组中的每个映射都被包裹在另一个数组中 =>

{ test url 2021-04-16 [[{2021-04-16 99.99}] [{2021-04-17 109.99}]] }

instead of

{ test url 2021-04-16 [{2021-04-16 99.99}, {2021-04-17 109.99}] }

有人知道如何解决这个问题吗? 提前致谢!

【问题讨论】:

  • 示例 json 不是有效的 json,这是为什么呢?错字?或者那不应该是 json 而是只类似于 json 的东西?
  • 你能分享item的类型的定义吗?
  • 我的错,我修复了 JSON(我错误地复制到问题中)并添加了项目的类型
  • 架构和检索到的数据看起来确实不一致。但是,检索到的数据是 you 存储在那里的数据,我想,所以在我看来,问题不在于您正在检索的内容,而在于您正在存储的内容。 如何确定您存储的项目与架构一致? 100%?你能展示一下你是如何进行存储的吗?数据在存储之前是什么样子的?
  • 我有点确定这个模式是一致的,哈哈。我很确定有很多可能性可以改进这个 JSON 模式,但我上面发布的只是我的一个想法,对我来说,它是有道理的。然而,由于我实际上是一个完整的 Go 和 MongoDB 菜鸟,我不确定这个问题是由 MongoDB、Go 还是 Go-Mongo 驱动程序引起的,这就是我想在这里问的原因。

标签: mongodb go fibers


【解决方案1】:

好的,我已经为我的用例找到了解决此问题的方法。

如上所述,Go 的 MongoDB 驱动程序将数组的每个条目包装到另一个相应的数组中,这导致嵌套数组。

在尝试了一段时间后,我发现将文档插入您的集合中,如下例所示,

db.collection.insertOne({ name: "Name", url: "URL", dateAdded: "2021-04-25", data: { "2021-04-25": 9.99, "2021-04-26": 19.99 } })

那么在您的程序中执行的查询结果如下所示:

{ ObjectID("60858245f8805dc57a716500") Name URL 2021-04-25 [{ 2021-04-25 9.99 } { 2021-04-26 19.99 }] }

这意味着 JSON 模式应该如下所示

{
    "ObjectId": {
        "name": "name",
        "url": "url",
        "dateAdded": "date",
        "data": {
            "2021-04-25": 9.99,
            "2021-04-26": 19.99
        }
    }
}

遗憾的是,我无法找出导致这种奇怪行为的真正原因,但我希望这对遇到此(或类似)问题的任何人有所帮助。

编辑

Data字段的类型更改为[]bson.M,正如mkopriva在下面的cmets中所说,修复它。

type Item struct {
    ID        primitive.ObjectID `json:"_id" bson:"_id"`
    Name      string             `json:"name" bson:"name"`
    URL       string             `json:"url" bson:"url"`
    DateAdded string             `json:"dateAdded" bson:"dateAdded"`
    Data      []bson.M           `json:"data" bson:"data"`
}

这样,原始 JSON 模式不必适应解决方法。

{
    "ObjectId":{
        "name":"name",
        "url":"url",
        "dateAdded":"date",
        "data": [
            {
                "2021-04-25": 9.99
            },
            {
                "2021-04-26": 19.99
            }
        ]
    }
}

【讨论】:

  • 我相信您可以通过将字段的类型更改为[]bson.M(一张地图)或bson.D(一张单键值对,通过单个我的意思是 one 切片中每个元素的 kv 对)。我认为,当您使用[]interface{} 时会发生什么,bson 默认将切片的各个interface{} 元素解组为bson.D,然后用它们填充切片。至少这是我从中收集到的信息:“解组到 interface{} 字段中的 BSON 文档将被解组为 D。”(我在上面的一个 cmets 中链接的文档中说明了这一点)。
  • 我刚刚尝试过[]bson.M,除此之外还有[]map[string]interface{},两者都以您希望的方式工作,fmt.Print 的输出看起来像[map[2021-04-25:9.99] map[2021-04-26:19.99]],相当于[{"2021-04-25": 9.99}, {"2021-04-26": 19.99}].
  • imgur.com/9mSzG7y -- 这就是你要找的不是吗?
  • 只有在您将数据库中的架构从 "data":[{...}] 更改为 "data":{...} 之后。尝试将原始模式的记录检索到 []map[string]interface{}[]bson.M 以使其正常工作。当我尝试使用 "data":{...} 检索记录时,我遇到与您相同的错误,当我尝试使用 "data":[{...}] 检索记录时,我在链接图像中得到结果。
  • 好的。现在就像一个魅力。我现在有点傻。非常感谢!非常感谢您的耐心、耐力和总体帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-07-08
  • 2017-07-11
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多