【问题标题】:MongoDB Relational Data Structures with array of _id's具有_id数组的MongoDB关系数据结构
【发布时间】:2015-02-01 18:48:10
【问题描述】:

我们使用 MongoDB 已有一段时间了,但有一件事我无法理解。假设我有一个用户集合,这些用户具有这样的观察列表或收藏项目列表:

usersCollection = [
    {
        _id: 1,
        name: "Rob",
        itemWatchList:[
            "111111",
            "222222",
            "333333"
        ]

    }
];

和一个单独的项目集合

itemsCollection = [
    {
        _id:"111111",
        name: "Laptop",
        price:1000.00
    },
    {
        _id:"222222",
        name: "Bike",
        price:123.00
    },
    {
        _id:"333333",
        name: "House",
        price:500000.00
    }
];

显然我们不想在 itemWatchList 数组中插入整个项目 obj,因为项目数据可能会改变,即价格。

假设我们将该用户拉到 GUI 并希望显示用户 itemWatchList 的网格。我们不能,因为我们只有一个 ID 列表。是做第二个 collection.find([itemWatchList]) 然后在结果回调中操纵用户记录以显示当前项目的唯一选择吗?问题在于,如果我返回一个由多个用户组成的数组,每个用户都带有一个 itemWatchList 的数组,那将是一个回调噩梦,试图保持结果直截了当。我知道 Map Reduce 或 Aggregation 框架无法遍历多个集合。

这里的最佳做法是什么?是否应该使用更好的数据结构来避免这个问题?

【问题讨论】:

  • 您当前的结构是理想的。您需要使用像猫鼬这样提供参考解析功能的模块。 -mongoosejs.com/docs/populate.html。 NodeJS 原生驱动 - 你需要自己做两个查询。

标签: node.js mongodb nosql


【解决方案1】:

您有 3 个不同的选项来显示关系数据。它们都不是完美的,但您选择的那个可能不是您用例的最佳选择。

选项 1 - 引用 ID 这是您选择的选项。保留 Id 列表,通常在要引用的对象数组中。稍后为了显示它们,您使用$in 查询进行第二次往返。

选项 2 - 子文档 对于您的情况,这可能是一个不好的解决方案。这意味着将存储在 items 集合中的整个文档数组作为子文档放入您的用户集合中。如果一次只有一个用户可以拥有一件物品,那就太好了。 (例如,不同的送货地址和帐单地址。)

选项 3 - 组合 这可能是您的最佳选择,但这意味着更改您的架构。例如,假设您的项目有 20 个属性,但您实际上只关心大多数屏幕的名称和价格。然后你就有了这样的架构:

usersCollection = [
    {
        _id: 1,
        name: "Rob",
        itemWatchList:[
            {
                _id:"111111",
                name: "Laptop",
                price:1000.00
            },
            {
                _id:"222222",
                name: "Bike",
                price:123.00
            },
            {
                _id:"333333",
                name: "House",
                price:500000.00
            }
        ]
    }
];

itemsCollection = [
    {
        _id:"111111",
        name: "Laptop",
        price:1000.00,
        otherAttributes: ...
    },
    {
        _id:"222222",
        name: "Bike",
        price:123.00
        otherAttributes: ...
    },
    {
        _id:"333333",
        name: "House",
        price:500000.00,
        otherAttributes: ...
    }
];

困难在于您必须使这些项目彼此同步。 (这就是最终一致性的含义。)如果您有一个低风险的应用程序(不是银行、医疗保健等),这没什么大不了的。您可以让两个更新查询连续发生,将拥有该项目的用户更新为新价格。如果您注意的话,您会在某些网站上注意到这种延迟。例如,当您打开实际页面时,即使您返回并刷新搜索结果,Ebay 搜索结果页面上的价格通常也会与实际价格不同。

祝你好运!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 2013-09-29
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    相关资源
    最近更新 更多