Вставка или обновление определенного поля


Требование

Мы хотим вставлять новый документ, если ни один из документов не соответствует заданному фильтру, но обновлять только определенное поле, когда совпадение найдено.

Текущее состояние коллекции favorite_books

{  "_id": {    "$oid": "6294228d3811a7c4c5044808"  },  "title": "My Brilliant Friend",  "author": "Elena Ferrante",  "year_published": 2012}
{  "_id": {    "$oid": "6294228d3811a7c4c5044809"  },  "title": "Lucy",  "author": "Jamaica Kincaid",  "year_published": 2002}
{  "_id": {    "$oid": "6294228d3811a7c4c504480a"  },  "title": "Cat's Cradle",  "author": "Kurt Vonnegut Jr.",  "year_published": 1998}
Вход в полноэкранный режим Выйти из полноэкранного режима

Подключение к базе данных

const uri = "mongodb://localhost:27017/?maxPoolSize=20&w=majority"
client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI(uri))

if err != nil {
    panic(err)
}
defer func() {
    if err = client.Disconnect(context.TODO()); err != nil {
        panic(err)
    }
}()
Войти в полноэкранный режим Выход из полноэкранного режима

Вставка или обновление

coll := client.Database("myDB").Collection("favorite_books")
filter := bson.D{
    {"title", "Lucy"},
    {"year_published", 1866},
}
opts := options.Update().SetUpsert(true)
updateData := bson.D{{"title", "Crime and Punishment"}, {"year_published", 1866}}
update := bson.D{{"$set", bson.D{{"author", "Fyodor Dostoyevsky"}}}, {"$setOnInsert", updateData}}
res, err := coll.UpdateOne(context.TODO(), filter, update, opts)

if err != nil {
    fmt.Println(err)
}

if res.MatchedCount != 0 {
    fmt.Println("matched and updated an existing document")
}

if res.UpsertedCount != 0 {
    fmt.Println("inserted a document with id: %vn", res.UpsertedID)
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Из документации по mongodb,

Вставка выполняет одно из следующих действий:

  • Обновить документы, соответствующие фильтру запроса
  • Вставить документ, если нет совпадений с фильтром запроса

Не существует документа, где title — Lucy, а year_published — 1866, поэтому приведенный выше код вставляет новый документ, и состояние коллекции меняется на:

{  "_id": {    "$oid": "6294228d3811a7c4c5044808"  },  "title": "My Brilliant Friend",  "author": "Elena Ferrante",  "year_published": 2012}
{  "_id": {    "$oid": "6294228d3811a7c4c5044809"  },  "title": "Lucy",  "author": "Jamaica Kincaid",  "year_published": 2002}
{  "_id": {    "$oid": "6294228d3811a7c4c504480a"  },  "title": "Cat's Cradle",  "author": "Kurt Vonnegut Jr.",  "year_published": 1998}
{  "_id": {    "$oid": "629424222932d1cc570ad0d0"  },  "title": "Crime and Punishment",  "year_published": 1866,  "author": "Fyodor Dostoyevsky"}
Войти в полноэкранный режим Выход из полноэкранного режима

Если мы изменим фильтр на

filter := bson.D{
    {"title", "Crime and Punishment"},
    {"year_published", 1866},
}
Войти в полноэкранный режим Выйти из полноэкранного режима

есть документ, который соответствует этому фильтру запроса, следовательно, мы можем обновить определенное поле строкой

update := bson.D{{"$set", bson.D{{"author", "Sasaki Kojirou"}}}, {"$setOnInsert", updateData}}
Войти в полноэкранный режим Выйти из полноэкранного режима

В результате мы получим следующую коллекцию:

{  "_id": {    "$oid": "6294228d3811a7c4c5044808"  },  "title": "My Brilliant Friend",  "author": "Elena Ferrante",  "year_published": 2012}
{  "_id": {    "$oid": "6294228d3811a7c4c5044809"  },  "title": "Lucy",  "author": "Jamaica Kincaid",  "year_published": 2002}
{  "_id": {    "$oid": "6294228d3811a7c4c504480a"  },  "title": "Cat's Cradle",  "author": "Kurt Vonnegut Jr.",  "year_published": 1998}
{  "_id": {    "$oid": "629424222932d1cc570ad0d0"  },  "title": "Crime and Punishment",  "year_published": 1866,  "author": "Sasaki Kojirou"}
Вход в полноэкранный режим Выход из полноэкранного режима

Примечание: Обратите внимание, что операторы полей $set и $setOnInsert не должны иметь одинаковые поля, так как это приведет к исключению записи.

Ссылка:

Вставка или обновление в одной операции
setOnInsert

Оцените статью
Procodings.ru
Добавить комментарий