Могу ли я узнать, почему у запроса MongoDB нет совпадений? - PullRequest
0 голосов
/ 08 января 2020

Я часто использую findOneAndUpdate для получения и обновления документов на основе нескольких условий, например:

const { value } = await collection.findOneAndUpdate(
  { _id: "abc", name: "xyz" },
  { $set: { ... } }
);

Если нет документа, соответствующего запросу, я хотел бы знать , почему совпадение не удалось, чтобы я мог возвращать пользователям полезные сообщения об ошибках. Например, если документа с _id == "abc" не существует, я хотел бы вернуть сообщение типа «Документ не найден». Если он существует, но имеет другой name, сообщение должно быть «Имя неверно». На данный момент я могу только выяснить, соответствует ли весь запрос путем проверки возвращенного value.

. Я, конечно, могу позвонить findOne({ _id: "abc" }), проверить, если name имеет правильное значение и после этого вызовите updateOne, но я бы предпочел одну операцию атома c.

Есть ли способ сделать это или мне нужно использовать транзакцию в этом случае?

Ответы [ 2 ]

0 голосов
/ 08 января 2020

Вы можете попробовать операцию обновления и, если возвращенное значение равно null (совпадение не найдено) - отправить сообщение пользователю приложения.

findOneAndUpdate(filter, update, options, callback) имеет findAndModifyCallback(error, result), а значение result будет null, если запрос на обновление не совпадет. См. Примечание ниже для параметра findOneAndUpdate returnOriginal:

Параметр returnOriginal является логическим true по умолчанию. Если документы не найдены, значение будет null по умолчанию (returnOriginal: true), даже если документ был отклонен; когда false, возвращает обновленный документ, а не оригинал. Установите значение false , и в случае, если вы используете опцию upsert, так что значение будет null в случае отсутствия совпадения.

Итак, если значение результата null, это означает, что запрос не совпал и обновление не произошло, и вы можете вернуть соответствующее сообщение. Как? Вам все еще нужно выполнить запрос find и:

if (id not found)
    send message "Document not found."
else // name not found
    send message "Name is incorrect."

Если вы не хотите снова запускать запрос find, просто отправьте generi c сообщение пользователю приложения.

Транзакции?

Если ваше развертывание является кластером с набором реплик или сегментированным, то возможны транзакций . Транзакции с примечаниями доступны только в последних версиях MongoDB (4.0 для наборов реплик и 4.2 для сегментированных кластеров).

0 голосов
/ 08 января 2020

Согласно примечаниям к реализации, findOneAndUpdate() возвращает Collection~findAndModifyCallback, т.е. обратный вызов результата сбора. Внутренний обратный вызов имеет два поля:

  • error (Экземпляр ошибки, представляющий ошибку во время выполнения.)
  • result (Объект результата, если команда была выполнена успешно.)

Этот результирующий объект внутренне содержит 3 значения,

  • значение (документ, возвращенный из команды findAndModify.)
  • lastErrorObject (Необработанный lastErrorObject, возвращенный из команды.)
  • ok (равно 1, если команда выполнена правильно.)

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


Ссылки

...