我必须创建一个文档集合,并且对正确的设计有疑问。
每个文档都是一个“身份”;每个身份都有“合作伙伴数据”列表;每个伙伴数据都由一个ID和一组数据定义。
一种方法可以是(1):
{
_id: ...
partners: [
{
id: partner1,
data: {
}
},
{
id: partner2,
data: {
}
},
]
}
另一种方法可以是(2)
{
_id: ...
partners: {
partner1: {
data: {
}
},
partner2: {
data: {
}
},
]
}
我更喜欢第一个身份,但是考虑到我可能有上百万个身份,这可能是表现最好的模式吗?
一个典型的查询可以是:“有多少个身份与ID为N的伙伴”。
在第二个示例中,查询可以是:
db.identities.find({partner.partnerName:{$ exists:true}})
采用第一种方法时,如何获得此计数? 第二种解决方案更易于处理服务器端;每个文档都会有一个列表,其中每个KEY是合作伙伴ID,因此我不必扫描所有文档,而只需按键即可获取合作伙伴数据...
您如何看待这些解决方案?我更喜欢第一个,但第二个我认为更“可用” ...
谢谢
答案 0 :(得分:0)
我更喜欢第一个身份,但是考虑到我可能有上百万个身份,这可能是表现最好的模式吗?
如果您要拥有数百万个身份,那么两种方法 并不是真正可扩展的。
mongo中的每个文档都有大小限制(16MB)(read about it here)
如果您将拥有很多身份, 可扩展的方法是创建一个不同的集合, 仅用于关系和伙伴关系数据。
现在,我也希望您考虑如何对待“伙伴关系”, 如果我是用户,并且您将我列入了合作伙伴列表,那么您会把我视为您的合作伙伴吗?
如果我们俩都将对方视为伙伴,那么mongo-db可能不是最佳解决方案。图数据库更适合处理这种类型的关系。
mongo中用于双向关系的所有解决方案都将基于双重更新(您的ID在我的合作伙伴列表中,我的ID在您的合作伙伴列表中)。 (在SQL中,您可以添加一个附加条件,但不能在mongo中添加), 因此,您无需保存两次合作关系。 (我和你,你和我) 只有你和我。
你知道这是怎么回事吗?
如果您只需要走一条路, 然后只需创建第二个集合“伙伴关系”
{
_id: should be uniqe,
user_id: 'your_id',
partner_id: 'his_id'
data: {} or just flatten the fields into the root object.
}
请注意,您为每个合作伙伴创建一行!
然后,您可以使用$ lookup来查询具有所有用户的用户 合作伙伴。
类似:
db.getCollection('partners').aggregate([
{
$lookup: {
from: 'parterships',
localField: '_id',
foreignField: 'user_id',
as: 'partners'
}
},
{
$project: {
name: 1,
partners: 1,
num_partners: { $size: "$partners" }
}
}
])
详细了解聚合阶段here。
如果您将没有太多的合伙企业,那么请继续 您的第一种方法很好。
第二种方法将使对该集合的大多数查询变得很奇怪,并且您将始终必须编写代码才能查询该表。 它不会是“直接”的mongo查询。