具有_id数组的MongoDB关系数据结构

时间:2014-12-04 01:26:03

标签: node.js mongodb nosql

我们一直在使用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数组的多个Users数组,那将是一个回调的噩梦,试图让结果保持平直。我知道Map Reduce或Aggregation框架无法遍历多个集合。

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

1 个答案:

答案 0 :(得分:0)

您有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在搜索结果页面上的价格通常与打开实际页面后的实际价格不同。

祝你好运!