В MongoDB db.collection.findOneAndUpdate()
метод актуализира единичен документ въз основа на filter
и sort
критерии.
collection
part е името на колекцията, с която да се извърши операцията.
Пример
Да предположим, че имаме колекция, наречена pets
който съдържа следните документи:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Можем да използваме db.collection.findOneAndUpdate()
метод за актуализиране на един от тези документи.
db.pets.findOneAndUpdate(
{ "type": "Dog" },
{ $set: { "type": "Cow" } }
)
Резултат:
{ "_id" : 1, "name" : "Wag", "type" : "Dog" }
По подразбиране той връща оригиналния документ (не модифицираната версия).
Имайте предвид, че само едно куче беше актуализирано, въпреки че в колекцията има две кучета.
Нека проверим колекцията.
db.pets.find()
Резултат:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Dog" } { "_id" : 3, "name" : "Meow", "type" : "Cat" }
Виждаме, че първият документ вече съдържа крава вместо куче.
Върнете модифицирания документ
По подразбиране оригиналният документ се връща, когато използвате db.collection.findOneAndUpdate()
.
Ако предпочитате вместо това да върнете модифицирания документ, използвайте returnNewDocument
параметър.
Нека направим още една модификация, но този път ще използваме returnNewDocument: true
.
db.pets.findOneAndUpdate(
{ "type": "Dog" },
{ $set: { "type": "Horse" } },
{ returnNewDocument: true }
)
Резултат:
{ "_id" : 2, "name" : "Bark", "type" : "Horse" }
Този път другото куче беше актуализирано. В този случай сме го променили на кон и можем да видим, че документът за връщане отразява това.
Нагоре
Upsert е опция, която можете да използвате при операции за актуализиране. Ако посоченият документ не съществува, се добавя нов. Ако го прави съществува, тогава оригиналният документ се актуализира (и не е вмъкнат документ).
Можете да извършвате upserts, като посочите upsert: true
.
Пример за използване на upsert: false
Първо, ето пример за опит за актуализиране на несъществуващ документ, когато upsert: false
.
db.pets.findOneAndUpdate(
{ "_id": 4 },
{ $set: { "name": "Barry", "type": "Badger" } },
{
returnNewDocument: true
}
)
Резултат:
null
Документът не съществуваше в колекцията и така findOneAndUpdate()
върна null
. Въпреки че не посочихме upsert: false
, знаем, че е невярно, защото това е стойността по подразбиране (т.е. това е стойността, която се използва, когато не посочите опция upsert).
Ако хвърлим още един поглед в колекцията, ще видим, че документът не е бил внесен.
db.pets.find()
Резултат:
{ "_id" : 1, "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Scratch", "type" : "Cat" }
Пример за използване на upsert: true
Ето го отново, но този път указваме upsert: true
.
db.pets.findOneAndUpdate(
{ "_id": 4 },
{ $set: { "name": "Barry", "type": "Badger" } },
{
upsert: true,
returnNewDocument: true
}
)
Резултат:
{ "_id" : 4, "name" : "Barry", "type" : "Badger" }
Този път се въвежда нов документ и ние виждаме въведения документ като изход (защото сме посочили returnNewDocument: true
).
Нека проверим колекцията отново.
db.pets.find()
Резултат:
{ "_id" : 1, "name" : "Wag", "type" : "Cow" } { "_id" : 2, "name" : "Bark", "type" : "Horse" } { "_id" : 3, "name" : "Meow", "type" : "Cat" } { "_id" : 4, "name" : "Barry", "type" : "Badger" }
Така че можем да видим, че новият документ всъщност е бил въведен.
arrayFilters
Параметър
Когато работите с масиви, можете да използвате arrayFilters
параметър заедно с позиционния $
оператор, за да определи кои елементи на масива да актуализира. Това ви позволява да актуализирате елемент на масив въз основа на неговата стойност, дори ако не знаете неговата позиция.
Например, да предположим, че имаме колекция, наречена players
със следните документи:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 17, 18 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
Бихме могли да изпълним следната заявка, за да актуализираме само онези елементи на масива, които имат стойност, по-висока от определено количество (в този случай 10).
db.players.findOneAndUpdate(
{ scores: { $gte: 10 } },
{ $set: { "scores.$[e]" : 10 } },
{
arrayFilters: [ { "e": { $gte: 10 } } ]
}
)
Резултат:
{ "_id" : 2, "scores" : [ 8, 17, 18 ] }
Това показва документа, преди да е бил актуализиран. Както се очаква, това актуализира само един документ, въпреки че два документа отговарят на критериите.
Ето как изглеждат документите сега.
db.players.find()
Резултат:
{ "_id" : 1, "scores" : [ 1, 5, 3 ] } { "_id" : 2, "scores" : [ 8, 10, 10 ] } { "_id" : 3, "scores" : [ 15, 11, 8 ] }
В документ 2 бяха актуализирани два елемента на масива, тъй като тези елементи отговаряха на критериите.
Повече информация
db.collection.findOneAndUpdate()
Методът приема и други параметри, като projection
(за да посочите подмножество от полета за връщане), sort
, maxTimeMS
и collation
.
Вижте документацията на MongoDB за db.collections.findOneAndUpdate()
за повече информация.