2014-02-15 3 views
2

Я ищу хороший способ реализации ключа сортировки, который полностью определяется пользователем. Например. Пользователь представлен списком и может сортировать элементы, перетаскивая их. Этот порядок должен быть сохранен.mongodb: моделирование пользовательского порядка сортировки

Один из часто используемых способов является просто создать поле типа сортировки по возрастанию целое в пределах каждого элемента:

{ 
    "_id": "xxx1", 
    "sort": 2 
}, 
{ 
    "_id": "xxx2", 
    "sort": 3 
}, 
{ 
    "_id": "xxx3", 
    "sort": 1 
} 

Хотя это, конечно, работать, он не может быть идеальным: В случае, если пользователь перемещает элемент из очень низкое до самого верха, все промежуточные индексы должны обновляться. Мы здесь не говорим о встроенных документах, поэтому это приведет к обновлению многих отдельных документов. Это может быть оптимизировано путем создания начальных значений сортировки с промежутками между ними (например, 100, 200, 300, 400). Однако это создаст необходимость в дополнительной логике повторной сортировки в случае исчерпания пространства между двумя элементами.

На ум приходит еще один подход: наличие родительского документа содержит отсортированный массив, который определяет порядок детей.

{ 
    "_id": "parent01", 
    "children": ["xxx3","xxx1","xxx2"] 
} 

Такой подход, безусловно, сделает его легче изменить порядок, но будет иметь это собственные предостережения: Родительские документы всегда должны следить за правильный список своих детей. Поскольку добавление детей будет обновлять несколько документов, это все еще может быть не идеальным. И должна быть сложная проверка входных данных, полученных от клиента, поскольку длина этого списка и содержащихся в нем элементов никогда не может быть изменена клиентом.

Есть ли лучший способ реализовать такой вариант использования?

+0

Второй вариант кажется мне более эффективным и выполнимым. Что вы подразумеваете под комплексной проверкой ввода, полученной от клиента? »Если вы просто хотите проверить, использует ли клиент действительные элементы, вы можете иметь вторую отдельную коллекцию с только допустимыми элементами для проверки этого. Кроме того, mongodb будет вскоре появится опция «вставить по индексу» (https://jira.mongodb.org/browse/SERVER-2363). – joao

+0

Спасибо, эта проблема возникла бы только в том случае, если клиенту будет разрешено отправлять обновленные если клиент отправляет необходимые шаги для воссоздания обновленного списка. Однако, вероятно, вы должны отправить этот комментарий в качестве ответа. –

ответ

1

Трудно сказать, какой вариант лучше, не зная:

  1. Как часто порядок сортировки обычно обновляется
  2. какие запросы вы собираетесь работать с документами и как часто
  3. Сколько документов может быть Сортировка за один раз

Уверен, что вы сделаете гораздо больше запросов, чем обновлений, поэтому лично я бы пошел с первым вариантом. Его легко реализовать, и это просто, что означает, что он будет перегибом. Я понимаю вашу озабоченность по поводу обновления нескольких документов, но обновления будут выполняться на месте, я имею в виду, что никаких изменений документов не произойдет, так как вы фактически не изменяете размер документов. Просто создайте простой тест. Сформировать 1k документов, а затем просто обновить каждый из них в цикле, как этот

db.test.update({ '_id': arrIds[i] }, { $set: { 'sort' : i } }) 

Вы увидите, что это будет довольно мгновенная операция.

Мне нравится второй вариант, с точки зрения программирования он выглядит более элегантным, но когда дело доходит до практики, вам обычно не очень важно, если ваше обновление занимает 10 миллисекунд вместо 5, если вы не делаете этого часто и Я уверен, что вы этого не сделаете, большинство приложений ориентированы на запросы.

EDIT: При обновлении нескольких документов, даже если это мгновенная операция, один может прийти с проблемой несогласованности, когда некоторые документы обновляются и некоторыми нет. В моем случае это действительно не проблема.Давайте рассмотрим пример, предположим, что есть список:

{ "_id" : 1, "sort" : 1 },{ "_id" : 2, "sort" : 4 },{ "_id" : 3, "sort" : 2 },{ "_id" : 4, "sort" : 3 } 

так упорядоченные идентификаторы должны выглядеть, что 1,3,4,2 согласно сортировки полей. Допустим, у нас есть сбой, когда мы хотим переместить id = 2 в начало. Эта ошибка возникает, когда мы только обновлены два документа, поэтому мы придумали следующее состояние как только удалось обновить идентификаторами 2 и 1:

{ "_id" : 1, "sort" : 2 },{ "_id" : 2, "sort" : 1 },{ "_id" : 3, "sort" : 2 },{ "_id" : 4, "sort" : 3 } 

данные находятся в неустойчивом состоянии, но все же мы можем отобразить список для исправления проблемы, порядок идентификаторов будет 2,1,3,4, если мы просто закажем его по полю сортировки. почему это не проблема в моем случае? потому что, когда происходит сбой, пользователь перенаправляется на страницу с ошибкой или получает сообщение об ошибке, для него очевидно, что что-то не так, и он должен попробовать еще раз, поэтому он просто идет на страницу и фиксирует заказ, который частично действительный для него.

Просто подводить итоги. Принимая во внимание, что это действительно редкий случай и другие преимущества подхода, с которым я бы пошел. В противном случае вам нужно будет разместить все в одном документе как элементы, так и массив с их индексами. Это может быть гораздо более серьезной проблемой, особенно когда дело доходит до запросов.

Надеюсь, это поможет!

+0

уверен, что у меня будет больше запросов, чем обновлений. У меня есть проблемы с несколькими обновлениями документов. что они могут занять много времени, но что-то может пойти не так, как надо, и пока вы не реализуете транзакционное поведение самостоятельно, это может оставить вас с поврежденными данными. Однако, что касается моделирования данных на основе документов, t здесь обычно это приятное решение, о котором вы, вероятно, не подумали бы без большого опыта в этой области. Вот почему я спрашивал. –

+0

На самом деле у меня была такая же проблема, и я просто хотел поделиться тем, что я узнал от нее, я не мог найти или придумать лучшее решение, и я буду очень рад, если кто-то предложит лучше здесь. Что касается проблемы согласованности, вы здесь абсолютно правдивы, но в моем случае это было не очень важно. Это очень маловероятно, и даже если это произойдет, это не повредит данные. Но, вероятно, для вашего решения это жизненно важно. Извините, я бы не стал волноваться за первый вариант, который мне просто не был достаточно ясным, что здесь важна последовательность. –

+0

хорошо, если что-то пойдет не так, если вы обновите значения сортировки, вы, скорее всего, закончите тем же значением сортировки, которое используется более одного раза, что, по крайней мере, приведет к неопределенному порядку сортировки для двух элементов. Если это будет эффективно проблемой, зависит от ожиданий пользователя и того, насколько хорошо приложение имеет дело с таким случаем. По крайней мере, это приведет к непоследовательности, которая почти всегда является чем-то вроде плохого. Я думаю, что лучше всего попытаться избежать обновления нескольких документов, когда это возможно. Но я еще не попал в производство, так что это гипотетически. –

Смежные вопросы