Насколько я знаю,
с $ set и $ setOnInsert, мы можем не обновить / вставить одно и то же поле.
т.е. $set и $ setOnInsert должны быть взаимоисключающими.
Работает при обновлении документа, но выдает исключение при вставке документа.
В случае обновления $ setOnInsertбудет игнорироваться.
В случае вставки оба будут выполнены.
Я думаю, что решение будет,
использовать returnNewDocument и иметь одинполе в схеме isUpdated
по умолчанию равно false.
Примечание:
убедитесь, что всякий раз, когда вы используете операцию «вставки» в коллекцию, вы не добавляете isUpdated
, который будет установлен в значение false, или в значение false. .
сформировать запрос, подобный
db.collection('users').findOneAndUpdate(
{ code: user.code },
{
$set: user, // which has user.isUpdated set to true
},
{
upsert: true,
returnNewDocument: false, // (by default it is false only)
}
);
С этой логикой
Итак, давайте пошагово,
Если документ doc1
отсутствует, он будет вставлен, и mongo вернет ответ null
. Вы узнаете, что это Вставлено .
Если документ doc2 присутствует (учитывая, что эта логика не применяется к ранее вставленному документу doc2
перед и isUpdated
поле отсутствует в doc2), оно будет выполнять $ set, поэтому в возвращаемом курсоре это поле отсутствует, т. Е. undefined
, поэтому, как вы знаете, оно обновлено .
допустим, мы снова запускаем тот же запрос для doc1
(который присутствует, и мы применили нашу новую логику), затем есть два случая
a. оно будет обновлено и в курсоре у нас будет isUpdated
, равный false.
b. оно будет обновлено и в курсоре у нас будет isUpdated
, равное true.
В обоих случаях вы знаете, что это Обновлено
Я думаю, что этот подход должен решить вашу проблему.
Пожалуйста, поделитесь, если это поможет вам, или вы нашли какое-либо другое решение.
ОБНОВЛЕНИЕ
Фактически
Вам даже не нужно другое поле isUpdated
, без этого поля это должно работать с той же логикой.
т.е. если курсоримеет значение null, а затем вставляется, если не является null, то обновляется.