让我们想象某种包含许多幻灯片的演示文稿。 mongo中的演示文稿集合可以表示为:
{
_id: <presentation_id>,
author: <author_name>,
...
}
还有幻灯片集合,其中包含这些演示文稿的幻灯片:
{
_id: <slide_id>,
presentation_id: <presentation_id>,
content: <content(html,text, etc.)>,
order: <slide_order (page number)> /* This field is used to place slides in correct order during showcase*/
}
与所有演示文稿一样,幻灯片可以添加,移动,删除等,并且应该在每次操作后自动保存更改。在每个幻灯片添加或移动时使用此类方案,我们需要使用他们的订单值更新大量幻灯片。在流星中,它会导致安静的大等待时间(例如,对于250张幻灯片的演示,如果我们在其开头添加1张幻灯片,我们需要在for
循环中更新250张现有幻灯片。)
我还想到了两件事如何解决这个问题:
1)添加到presentation
新字段slides
,该字段将是按顺序包含幻灯片ID的数组。但是这种方式在排序方面存在问题:现在mongodb不能按ID数组排序结果(在&lt; = 2.4版本中有使用$or
的黑客攻击,但在2.6中它不再可用)没有使用聚合框架(它不会出现在流星体中,需要额外的模块)。这将通过一次大更新取代大量的小更新。
2)另一种方法是使用两个新字段替换幻灯片集合中的order
字段:prev
和next
,并仅保存下一张和上一张幻灯片ID。这将减少(重新)移动/添加操作到少量小更新,但是当我需要显示所有幻灯片时,我需要分两步执行此操作:以不正确的顺序从db获取幻灯片,找到第一个(最后一个)使用next / prev&#34;链接&#34;。
首选哪种方式?或者可能有另一种更好的方法来做到这一点?
答案 0 :(得分:1)
最好的方法可能是将幻灯片移动到演示文稿中的数组。
因为在几乎所有用于幻灯片集合的用例中,您都需要来自演示文稿集合的数据。数组始终是有序的,因此您不需要/需要幻灯片的_id字段。
唯一的限制是总演示文稿不能超过16兆字节。
然后,您可以使用mongodb的array update modifiers在集合中移动幻灯片。 $position modifier对添加特别有用。 你可以结合$splice and $push来移动东西。
编辑:在更新中使用$ inc,例如:
在订单中间插入幻灯片:
col.update({presentation_id:xxx, order:{$gte:20}},{$inc:{order:1}},{multi:true});
col.insert({order:20, presentation_id:xxx/*otherdata*/});
这增加了从20开始的所有顺序字段,因此必须释放位置20.这使用mongos自己的光标而不是for循环,所以应该是一个快得多的地狱。
移动文档:
var moveSlide = col.findOne({presentation_id:xxx, order:20});
col.update({presentation_id:xxx, {order:{$lte:20}}},{$inc:{order:1}},{multi:true});
col.update(moveSlide._id, {$set:{order:1}});
移动文档:
var moveSlide = col.findOne({presentation_id:xxx, order:20});
col.update({presentation_id:xxx, $and:[{order:{$lte:100}}, {order:{$gte:20}}]},{$inc:{order:-1}},{multi:true});
col.update(moveSlide._id, {$set:{order:100}});