В чем разница между findAndModify и update в MongoDB?

Я немного смущен findAndModify метод в MongoDB. В чем преимущество этого перед update способ? Мне кажется, что он просто возвращает первый элемент, а затем обновляет ее. Но почему мне нужно сначала вернуть товар? Я прочитал MongoDB: окончательное руководство и он говорит, что он удобен для управления очередями и выполнения других операций, которые нуждаются в атомарности стиля get-and-set. Но я не понимал, как он этого добивается. Мочь кто-нибудь объяснит мне это?

4 ответов


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

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


findAndModify возвращает документ, обновление не.

Если я правильно понял Дуайта Мерримена (одного из оригинальных авторов mongoDB), использование update для изменения одного документа, т. е.("multi":false} также является атомарным. В настоящее время это также должно быть быстрее, чем делать эквивалентное обновление с помощью findAndModify.


с MongoDB docs (Курсив мой):

  • по умолчанию обе операции изменяют один документ. Однако метод update () с его multi option можно изменить более одного документа.

  • Если несколько документов соответствуют критериям обновления, для findAndModify(), вы можно указать порядок сортировки чтобы обеспечить некоторый контроль над тем, какой документ обновлять. По умолчанию поведение метода update (), вы не можете указать, какой один документ для обновления, когда несколько документов совпадают.

  • по умолчанию метод findAndModify ()возвращает предварительно измененная версия документ. Чтобы получить обновленный документ, используйте параметр new. Метод update () возвращает объект WriteResult, содержащий состояние операции. Чтобы вернуть обновленный документ, используйте метод find (). Однако другие обновления могут измените документ между обновлением и извлечением документа. Кроме того, если обновление изменило только один документ, но совпало несколько документов, необходимо использовать дополнительную логику для идентификации обновленного документа.

  • вы не можете указать проблему записи для findAndModify (), чтобы переопределить проблему записи по умолчанию, тогда как, начиная с MongoDB 2.6, вы можно указать проблему записи к методу update ().

при изменении одного документа оба метода findAndModify() и update() атомарно обновляют документ.


один полезный класс вариантов использования-счетчики и аналогичные случаи. Например, взгляните на этот код (один из тестов MongoDB): find_and_modify4.js.

таким образом, с findAndModify вы увеличиваете счетчик и получаете его приращение значение в одном шаге. Сравните: если вы (A) выполните эту операцию в два этапа и кто-то другой (B) выполняет ту же операцию между вашими шагами, тогда A и B могут вам же последнее значение счетчика вместо двух разных (только один пример возможные проблемы.)