问题
我需要将一个定义为“整体”的文档建模到一个小的固定集合“部件”,在这个集合中,整体及其部分都是可查询的。
切片派是我需要的模型的一个很好的例子。进一步说明该领域:
问题是:
考虑到以上各点,如何对pie及其slices进行有效的查询(如果可能的话,有效地存储)?
如果这很明显,请回答。阅读我迄今尝试过的两种方法,以及为什么这两种方法都不令人满意。
我试过的是:
1.嵌入
将部分嵌入到整个似乎是自然的选择中。
Pie {
type: String, // `type` and other shared attrs are defined on Pie
slices: [{
_id: ObjectId
weight: Number
}]
}有了这个,我可以按类型、重量、切片重量查询馅饼,也可以通过aggregate、unzip和project查询各个樱桃饼片。
问题在于如何在单个片上对进行排序和查询。例如,如果我需要从所有馅饼中检索5个最重的切片(如上面的问题所述),该怎么办?我--这是可能的--聚合,我不知道怎么做。
2.单独的集合
在放弃了第一个模式之后,我又回到了使用两个单独的集合,并加入了一个引用id:
Pie {
type: String // `type` and other shared attrs are defined on Pie ...
}
Slice {
pie_id: ObjectId,
type: String, // ... and duplicated to all slices
weight: Number
}这解决了我的查询问题,但介绍了更多。这里只复制了type。在我的实际应用程序中,这要糟糕得多,以至于我对Slice的模拟可能是90%的重复数据。
另一个问题是,每当我想要查询馅饼时,我必须再次查询所有的切片。此外,制作饼不再是原子操作,而是一批单独的插入。
发布于 2013-09-16 01:14:13
我的答案,虽然也许不是唯一或最好的答案,是去或不正确的数据在双方的关系。
本质上,slices嵌入在pie文档中,和--切片存在于它们自己的集合中,完整地包含了重复的pie元数据。通过这种方式,可以独立地查询饼及其切片,而无需进行任何辅助查询。
双向复制存储有效吗?也许不会,但同样,存储在这里也不是问题。
这是否使更新文档变得更加复杂和多个操作?是的,但是更新将远比读取少得多,在这种情况下,读要重要得多。
发布于 2013-02-06 22:28:45
您看过这个吗?特别是http://docs.mongodb.org/manual/tutorial/model-tree-structures/,“带有子引用的模型树结构”似乎正是您所要寻找的。您只能在切片文档中存储最特定于特定切片的数据(例如片权重),以及在Pie文档中存储其他所有数据。
发布于 2013-02-06 22:54:50
你能用这样的结构吗?
{
"_id" : ObjectId("5112d747819e326e6c37e1e3"),
"pie" : {
"type" : "cherry",
"weight" : 500,
"slices" : [
{
"slice_id" : ObjectId("5112d747819e326e6c37e1e1"),
"type" : "square",
"weight" : 75
},
{
"slice_id" : ObjectId("5112d747819e326e6c37e1e2"),
"type" : "triangle",
"weight" : 75
}
]
}
}然后您可以使用$unwind和$sort,例如:
db.q14735834.aggregate({$unwind: "$pie.slices"}, {$sort: {"pie.slices.weight":-1}}, {$limit:10})以及进一步组合$group和其他聚合框架操作符来操作数据。
除了Alptigin引用的教程之外,聚合框架文档还可以使用:http://docs.mongodb.org/manual/applications/aggregation/
https://stackoverflow.com/questions/14735834
复制相似问题