Есть ли у Mongoose способ запрашивать документы и создавать новые, если они не существуют, все в одном запросе? - PullRequest
0 голосов
/ 04 марта 2019

Я пытаюсь выяснить, как обновить коллекцию в моем MongoDB.По сути, я хочу взять список адресов электронной почты, проверить, существуют ли они в БД, а если нет, создать из них нового пользователя, все в одном запросе.Это возможно?

Сейчас я делаю это:

const usersWithEmailsOnly = [<array-of-emails];

User.update({
   email: {
      $in: usersWithEmailsOnly.map(userWithEmail => userWithEmail.email),
   },
}, { multi: true, upsert: true }).exec()

И я получаю ответ от сервера:

{ ok: 0, n: 0, nModified: 0 }

И когда я смотрю на БД, я вижу, что пользователи не создаются.Есть ли что-то еще, что мне нужно сделать?

1 Ответ

0 голосов
/ 05 марта 2019

Вы хотите bulkWrite()

Users.bulkWrite(
  usersWithEmailsOnly.map(userWithEmail =>
    ({ 
      "updateOne": {
        "filter": { "email": userWithEmail.email },
        "update": { "$setOnInsert": { "name": userWithEmail.name } },
        "upsert": true
      }
    })
  )
)

Это объединяется с оператором обновления $setOnInsert, который имеет специальное условие, что он указывает аргументы только обновляет документ, когда происходит фактический "upsert / insert" .Таким образом, существующий документ, для которого выполняется сопоставление, просто не получает изменений, когда используется только этот оператор.

Обратите внимание, что "upserts" всегда будет применять критерии, используемые в запросе / предикате часть оператора обновления, если выражение равно единственному значению;то есть age: { $gt: 3 } не будет единичным .Для большинства «загрузки данных» обычно требуется создать статический предикат в качестве «уникального ключа» и, следовательно, селектор для обновления, а также некоторые другиеданные, к которым можно применить $setOnInsert по мере необходимости.

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

Не существует такой вещи, как истинная «один оператор» , поскольку различные критерии для обновляемых данных не могут применяться к нескольким документам в обновлении MongoDB.Вы можете применить одинаковые данные для обновления нескольких документов, но когда вы хотите, чтобы «это условие соответствовало документу, также означает, что я обновляюсь с этими конкретными данными, когда это происходит» , тогдаэто то, что вы используете bulkWrite() для.

...