Безопасный + эффективный способ изменения объектов Mongo при переборе курсора?

У меня есть код, который проверяет каждый объект в коллекции Mongo (перебирает результат поиска () без параметров) и вносит изменения в некоторые из них. Кажется, что это небезопасно: мои изменения сохраняются, но затем, когда я продолжаю перебирать курсор, подмножество измененных объектов (10-15%) появляется во второй раз. Я не менял идентификатор документа или что-то еще, на что есть индекс.

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

Я заметил, что результат поиска () по умолчанию, похоже, не имеет определенного порядка, поэтому я попытался поместить явную сортировку в курсор, {"_id":1}. Кажется, это решило проблему - теперь ничего не появляется дважды, независимо от того, что я изменяю. Но я не знаю, хороший ли это / надежный подход. Насколько я могу судить из документации, добавление сортировки не заставляет предварительно запрашивать все идентификаторы; если это так, это хорошо, но тогда я не знаю, почему это решило бы проблему.

Это просто плохая идея использовать курсоры при изменении материала?

Я использую Scala/Casbah, если это имеет значение.

2 ответа

Похоже, что вы хотите, это запрос снимка. Вот больше информации о том, как это сделать:

http://www.mongodb.org/display/DOCS/How+to+do+Snapshotted+Queries+in+the+Mongo+Database

Рассмотрите возможность использования update Команда, которая изменяет несколько документов: http://docs.mongodb.org/manual/tutorial/modify-documents/

Кроме того, поскольку вы изменяете только некоторые объекты, рассмотрите возможность использования запроса, который возвращает только те документы, которые вы на самом деле собираетесь изменить, вместо сканирования всей коллекции.

Итерация по результату find и изменение объектов может показаться более удобным и гибким, поскольку вы не ограничены тем, что вы можете делать с операторами обновления, и вы можете написать код на выбранном вами языке для изменения документа. Однако есть проблема, которую вы описали, а также другие ограничения:

http://docs.mongodb.org/manual/faq/developers/

Например, запросы моментальных снимков не являются на 100% безопасными, и их нельзя использовать с коллекцией с сегментированием, поэтому, если позже вы решите использовать сегментирование, ваше решение будет нарушено.

Если вам нужно изменить очень большое количество объектов более сложным способом, возможно, map-Reduce или конвейер агрегации могут быть способом решения вашей проблемы:

http://docs.mongodb.org/manual/core/aggregation-pipeline/

http://docs.mongodb.org/manual/core/map-reduce/

Другие вопросы по тегам