我需要将一个被定义为“整体”的文档建模为一个小的,固定的“部分”集合,其中整体及其部分都是可查询的。
切片馅饼是我需要的模型的一个很好的例子。进一步描述域名:
鉴于以上几点,如何模拟pie
及其slices
是否可以有效查询(如果可能,有效存储)?
如果这很明显,请回答。请继续阅读我迄今为止尝试的两种方法,以及为什么两种方法都不令人满意。
1。嵌入
将部件嵌入整个seemed to be the natural choice内。
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%的重复数据。
另一个问题是,现在每当我想查询馅饼时,我都要再次查询所有切片。更进一步使馅饼不再是原子操作,而是一批单独的插入。
答案 0 :(得分:0)
你看过这个:http://docs.mongodb.org/manual/tutorial/model-tree-structures/ 特别是,“带有子引用的模型树结构”似乎正是您正在寻找的。您只能存储切片文档中特定切片的特定数据(例如切片重量)以及饼图文档中的所有其他内容。
答案 1 :(得分:0)
你能使用像这样的结构吗?
{
"_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 Jalayr]引用的教程之外,聚合框架文档可能有用:http://docs.mongodb.org/manual/applications/aggregation/
答案 2 :(得分:0)
我接下来的答案,虽然可能不是唯一或最好的答案,但是要对关系双方的数据进行非规范化。
基本上,slices
嵌入在pie
文档中的entiredy中, 和 切片存在于自己的集合中,并且重复{ {1}}元数据。通过这种方式,可以独立查询饼图及其切片,无需任何二次查询。
双向复制存储是否有效?可能不会,但是再次存储不是问题。
这是否会使更新文档更加复杂和多次操作?是的,但是更新会发生很远,远远少于读取,这在这种情况下更为重要。