Представим, что есть какая-то презентация, содержащая много слайдов. Коллекция презентаций в монго может быть представлена так:
{
_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 слайд в ее начало, нам нужно обновить 250 существующих слайдов в цикле for
).
Я также подумал о двух вещах, как с этим справиться: 1) Добавить в presentation
новое поле slides
, которое будет массивом, содержащим идентификаторы слайдов в последовательном порядке. Но у этого способа есть проблема с упорядочением: на данный момент mongodb не может упорядочить результаты по массиву id (в версиях ‹=2.4 был хак с использованием $or
, но в 2.6 он уже недоступен) без использования фреймворка агрегации (которого нет). т присутствует в метеоре из коробки и требует дополнительных модулей). Это заменит большое количество небольших обновлений одним большим обновлением.
2) Другой способ — заменить поле order
в коллекции слайдов двумя новыми полями: prev
и next
и сохранить только идентификаторы следующего и предыдущего слайдов. Это уменьшит (повторно) операции перемещения/добавления до нескольких небольших обновлений, но когда мне нужно показать все слайды, мне нужно будет сделать это в два этапа: получить слайды из БД в неправильном порядке, найти первый (последний) слайд и восстановить правильный порядок, используя следующие/предыдущие «ссылки».
Какой способ предпочтительнее? Или может есть другой лучший способ сделать это?
slide_id
) вниз (newPos › oldPos):Slides.update({pres_id: pres_id, _id:{$ne:slide_id}, $and: [{order: {$gte: oldPos}}, {order: {$lte: newPos}}]}, {$inc: {order: -1}}, {multi: true});
Вверх:Slides.update({pres_id: pres_id, _id:$ne:slide_id}, $and: [{order: {$lt: oldPos}},{order: {$gte: newPos}}]}, {$inc: {order: 1}}, {multi: true});
Когда элемент перемещается вниз, порядок элементов вышеnewPos
должен уменьшаться, и нам также не нужно делайте что-нибудь с элементами нижеnewPos
, то же самое с перемещением элемента вверх. 03.07.2014