我们一直在使用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框架无法遍历多个集合。
这里的最佳做法是什么?是否应该使用更好的数据结构来避免这个问题?
答案 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在搜索结果页面上的价格通常与打开实际页面后的实际价格不同。
祝你好运!