Upsert в MongoDB

Опубликовано: 5 Октября, 2022

В MongoDB upsert — это опция, которая используется для операции обновления, например, update(), findAndModify() и т. д. Или, другими словами, upsert — это комбинация обновления и вставки (обновление + вставка = upsert). Если значение этого параметра равно true и найден документ или документы, соответствующие указанному запросу, то операция обновления обновит соответствующий документ или документы. Или, если значение этой опции установлено в true и ни один документ или документы не соответствуют указанному документу, то эта опция вставляет новый документ в коллекцию, и этот новый документ имеет поля, указанные в операции. По умолчанию значение параметра upsert равно false. Если значение upsert в сегментированной коллекции равно true, вам необходимо включить в фильтр полный ключ сегмента.

Синтаксис:

upsert: <boolean>

Значение параметра upsert либо истинно, либо ложно.

Теперь мы изучим использование опции upsert:

Upsert с помощью метода findAndModify():

Мы можем использовать опцию upsert с методом findAndModify(). В этом методе значение этого параметра по умолчанию равно false. Если мы установим значение этой опции в true, то метод выполняет одну из следующих операций:

  • Если найден документ или документы, соответствующие заданным критериям запроса, то метод findAndModify() обновляет документ/документы.
  • Если ни один документ/документы не соответствуют заданным критериям запроса, метод findAndModify() вставляет в коллекцию новый документ.

Синтаксис:

db.Collection_name.findAndModify(

{

    selection_criteria:<document>,

    sort: <document>,

    remove: <boolean>,

    update: <document>,

    new: <boolean>,

    fields: <document>,

    upsert: <boolean>,

    bypassDocumentValidation: <boolean>,

    writeConcern: <document>,

    collation: <document>,

    arrayFilters: [ <filterdocument1>, … ]

})

Например:

В этом примере мы работаем с

Database: gfg

Collection: employee

Database: three documents that contains details of employees

Теперь мы собираемся вставить новый документ в коллекцию сотрудников, установив для параметра upsert значение true.

 db.employee.findAndModify({query:{name:"Ram"}, 
                            update:{$set:{department:"Development"}},
                            upsert:true})

Здесь ни один документ не соответствует имени «Рам», поэтому метод findAndModify() вставляет новый документ, содержащий два поля (т. е. имя: «Рам» и отдел: «Разработка»), поскольку значение параметра upsert установлено равным истинный.

Upsert с помощью метода update():

Мы можем использовать опцию upsert с методом update(). В этом методе значение этого параметра по умолчанию равно false. Если мы установим значение этой опции в true, то метод выполняет одну из следующих операций:

  • Если найден документ или документы, соответствующие заданным критериям запроса, метод update() обновляет документ/документы.
  • Если ни один документ/документы не соответствуют заданным критериям запроса, метод update() вставляет новый документ в коллекцию.

Примечание. Чтобы MongoDB не вставляла один и тот же документ более одного раза, создайте уникальный индекс в поле имени. С уникальным индексом, если для нескольких документов требуется одно и то же обновление с upsert: true, только одна операция обновления успешно вставляет новый документ.

Синтаксис:

db.Collection_name.update({Selection_criteria}, {$set:{Update_data}}, {

     upsert: <boolean>,

     multi: <boolean>,

     writeConcern: <document>,

     collation: <document>,

     arrayFilters: [ <filterdocument1>, … ],

     hint:  <document|string>        

   })

Например:

В этом примере мы работаем с

Database: gfg

Collection: employee

Database: three documents that contains details of employees

Теперь мы собираемся вставить новый документ в коллекцию сотрудников, установив для параметра upsert значение true.

db.employee.update({name:"Priya"}, {$set: {department: "HR"}},{upsert:true})

Здесь ни один документ не соответствует имени «Прия», поэтому метод update() вставляет новый документ, содержащий два поля (например, имя: «Прия» и отдел: «HR»), поскольку значение параметра upsert установлено равным истинный.

Upsert с операторными выражениями:

Если ни один документ не соответствует фильтру из данной коллекции, а параметр обновления является документом, содержащим операторы обновления, а также для параметра upsert установлено значение true, то операция обновления создает новые документы из предложений равенства в данном параметре запроса и применяет выражения из параметра обновления. Или, другими словами, когда значение параметра upsert равно true и ни один документ не соответствует данному фильтру, тогда операция обновления вставляет новый документ в данную коллекцию, а поля, вставленные в этот новый документ, являются полями, указанными в запросе. и обновить документы.

Пример:

В этом примере мы работаем с

Database: gfg

Collection: example

Database: five documents that contains details of students

Теперь мы собираемся вставить новый документ в коллекцию примеров, установив для параметра upsert значение true.

db.example.update({Name: "Rekha"},   // Query parameter  
                  {$set: {Phone: "7841235468 "}, // Update document
                   $setOnInsert: {Gender: "Female"}},
                  {upsert: true})

Здесь метод update() создает новый документ с полем «Имя: Рекха» из условия запроса, а затем применяет к этому документу операции $set и $setOnInsert.

Upsert с документом замены:

Если ни один документ не соответствует фильтру из данной коллекции, а параметр обновления содержит замещающий документ, значение upsert document также устанавливается равным true, операция обновления вставляет новый документ в коллекцию, а поля, вставленные в этот новый документ, являются поля, которые указываются в замещающем документе. Здесь, если замещающий документ содержит поле _id, MongoDB не создает новое поле _id для нового документа. Или, если замещающий документ не содержит поля _id, MongoDB создает новое поле _id для нового документа.

Примечание. Нельзя указывать разные значения поля _id в параметре запроса и замещающем документе. Если вы это сделаете, то вы получите ошибки.

Пример:

В этом примере мы работаем с

Database: gfg

Collection: example

Database: four documents that contains details of students

Теперь мы собираемся вставить новый документ в коллекцию примеров, установив для параметра upsert значение true.

db.example.update({Name:"Hema"}, // Query parameter
                  {Name:"Hema", Phone:8332564578}, // Replacement document
                  {upsert:true})

Upsert с конвейером агрегации:

Конвейер агрегации является многоэтапным конвейером, поэтому в каждом состоянии документы принимаются в качестве входных данных и создают результирующий набор документов, теперь на следующем этапе (идентификатор доступен) результирующие документы принимаются в качестве входных данных и производят выходные данные, этот процесс продолжается. до последнего этапа. В конвейере может быть от 1 до n стадий.

Если ни один документ не соответствует заданному фильтру, а параметр обновления содержит конвейер агрегации, также для параметра upsert устанавливается значение true, тогда операция обновления вставляет новый документ в коллекцию. Этот новый документ создается из предложения равенства, присутствующего в параметре запроса, и после этого применяется конвейер к документу для создания документа для вставки.

Пример:

В этом примере мы работаем с

Database: gfg

Collection: employee

Database: three documents that contains details of employees

Теперь мы собираемся вставить новый документ в коллекцию сотрудников, установив для параметра upsert значение true.

db.employee.update({name:”Ram”}, [{$set: {department: “HR”, age:30}}],{upsert:true})

Upsert с точечным запросом _id:

До сих пор мы изучали, что метод update() может изменять данные в коллекции на основе запроса, и если какой-либо соответствующий документ не найден с помощью опции upsert, в коллекцию можно добавить новое поле. Но upsert с точечным запросом _id является исключением, и если вы попытаетесь вставить документ таким образом, MongoDB покажет вам ошибку.

Пример:

Рассмотрим следующую операцию обновления. Поскольку операция обновления указывает upsert:true, а запрос указывает условия для поля _id с использованием записи через точку, обновление приведет к ошибке при создании документа для вставки.

db.employee.update({“_id.name”:”Roma”, “_id.uid”:0},{age:20}, {upsert:true})