Я немного смущен методом findAndModify
в MongoDB. Каково преимущество этого метода update
? Для меня кажется, что он просто возвращает элемент первым, а затем обновляет его. Но почему мне нужно сначала вернуть элемент? Я прочитал MongoDB: окончательное руководство, и он говорит, что он удобен для манипулирования очередями и выполнения других операций, требующих атомарности стиля get-and-set. Но я не понимал, как это достигается. Может ли кто-нибудь объяснить это мне?
Какая разница между findAndModify и обновлением в MongoDB?
Ответ 1
Если вы извлечете элемент и затем обновите его, может быть обновление другим потоком между этими двумя шагами. Если вы сначала обновите элемент, а затем извлечете его, может быть другое промежуточное обновление, и вы получите другой элемент, чем тот, который вы обновили.
Выполнение этого "атомарного" означает, что вам гарантировано, что вы возвращаете тот же самый объект, который вы обновляете, т.е. никакая другая операция не может произойти между ними.
Ответ 2
findAndModify
возвращает документ, обновление не выполняется.
Если я правильно понял Dwight Merriman (один из оригинальных авторов mongoDB), используя обновление, чтобы изменить один документ, т.е. ( "multi": false} также является атомарным. В настоящее время он также должен быть быстрее, чем выполнение эквивалентного обновления используя findAndModify
.
Ответ 3
Из Документы MongoDB (выделено мной):
По умолчанию обе операции изменяют один документ. Однако метод update() с его опцией может изменять более одного документа.
Если несколько документов соответствуют критериям обновления, для findAndModify() вы можете указать сортировку, чтобы обеспечить определенную степень контроля над тем, какой документ обновлять. При поведении метода update() по умолчанию вы не можете указать, какой один документ нужно обновить, если несколько документов совпадают.
По умолчанию метод findAndModify() возвращает предварительно измененную версию документа . Чтобы получить обновленный документ, используйте новый вариант. Метод update() возвращает объект WriteResult, который содержит статус операции. Чтобы вернуть обновленный документ, используйте метод find(). Однако другие обновления могут изменить документ между вашим обновлением и извлечением документа. Кроме того, если обновление изменило только один документ, но несколько документов соответствовали, вам нужно будет использовать дополнительную логику для идентификации обновленного документа.
Вы не можете указать проблему с записью findAndModify(), чтобы переопределить проблему записи по умолчанию, тогда как, начиная с MongoDB 2.6, вы можете указать проблему записи на метод update().
При изменении одного документа оба метода findAndModify() и update() автоматически обновляют документ.
Ответ 4
Один полезный класс вариантов использования - это счетчики и подобные случаи. Например, взгляните на этот код (один из тестов MongoDB): find_and_modify4.js.
Таким образом, при findAndModify
вы увеличиваете счетчик и получаете его прирост
значение за один шаг. Сравните: если вы (A) выполните эту операцию в два этапа и выполните
кто-то другой (B) выполняет ту же операцию между вашими шагами, тогда A и B могут
получить одно и то же последнее значение счетчика вместо двух разных (только один пример возможных проблем).