Въведение
Когато използвате MongoDB, ще прекарвате по-голямата част от времето си в управление на документи по някакъв или друг начин. Независимо дали създавате нови документи и ги добавяте към колекции, извличате документи, актуализирате данни или премахвате остарели елементи, документите са в центъра на модела MongoDB.
В това ръководство ще разгледаме какво представляват документите на MongoDB и след това ще покрием общите операции, за които вероятно ще трябва да знаете, за да управлявате среда, ориентирана към документи.
Какво представляват документите на MongoDB?
В MongoDB всички данни в базите данни и колекциите се съхраняват в документи. Тъй като колекциите не посочват задължителна схема по подразбиране, документите в колекцията могат да съдържат произволно сложна структура и не е необходимо да съвпадат с формата, използван от братските документи. Това осигурява невероятна гъвкавост и позволява на схемата да се развива органично при промяна на изискванията на приложението.
Самите документи на MongoDB използват формата за сериализиране на данни BSON, двоично представяне на JSON JavaScript обектната нотация. Това осигурява организирана структура с дефинирани типове данни, които могат да бъдат запитвани и работещи с тях програмно.
BSON документите са представени с двойка къдрави скоби ({}
), които съдържат двойки ключ-стойност. В BSON тези куплети с данни са известни като поле и неговата стойност . Полето е първо и е представено от низ. Стойността може да бъде всеки валиден тип данни BSON. Двоеточие (:
) разделя полето от неговата стойност. За разделяне на всяко поле и двойка стойности една от друга се използва запетая.
Като пример, ето валиден BSON документ, който MongoDB може да разбере:
{ _id: 80380, vehicle_type: "car", mileage: 7377.80, color: "blue", markets: [ "US", "UK" ], options: { transmission: "automatic", num_doors: 4, power_windows: true }}
Тук можем да видим доста видове:
_id
е цяло числоvehicle_type
иcolor
са низовеmileage
е плувкаmarkets
е масив от низовеoptions
съдържа вложен документ със стойности, състоящи се от низ, цяло число и булева
Поради тази гъвкавост документите са доста гъвкава среда за съхранение на данни. Нови полета могат да се добавят лесно, документи могат да бъдат вградени един в друг, а структурната сложност точно съответства на съхраняваните данни.
Как да създавам нови документи
За да създадете нов документ, преминете към база данни, където искате да съхранявате създадения документ. Ще използваме school
база данни за демонстрационни цели в тази статия:
use school
Вие също ще искате да изберете колекцията, където искате да вмъкнете документите. Както при базите данни, не е нужно изрично да създавате колекцията, където искате да вмъкнете документа. MongoDB автоматично ще го създаде, когато бъдат записани първите данни. За този пример ще използваме колекция, наречена students
.
След като вече знаете къде ще се съхранява документът, можете да вмъкнете нов документ, като използвате един от следните методи.
Използване на insert()
метод
insert()
методът ви позволява да вмъкнете един или повече документи в колекцията, към която е извикан.
За да вмъкнете един документ, предайте документа на метода, като го извикате в колекцията. Тук вмъкваме нов документ за ученик на име Ашли:
db.students.insert( { first_name: "Ashley", last_name: "Jenkins", dob: new Date("January 08, 2003"), grade_level: 8 })
WriteResult({ "nInserted" : 1 })
Ако искате да вмъкнете повече от един документ едновременно, вместо да предавате документ на insert()
, предайте масив от документи. Можем да добавим два нови документа за ученици на име Брайън и Лия:
db.students.insert( [ { first_name: "Brian", last_name: "McMantis", dob: new Date("September 18, 2010"), grade_level: 2 }, { first_name: "Leah", last_name: "Drake", dob: new Date("October 03, 2009") } ])
BulkWriteResult({ "writeErrors" : [ ], "writeConcernErrors" : [ ], "nInserted" : 2, "nUpserted" : 0, "nMatched" : 0, "nModified" : 0, "nRemoved" : 0, "upserted" : [ ]})
Тъй като извършихме операция за групово записване, нашата връщана стойност е BulkWriteResult
вместо WriteResult
обект, който сме виждали преди.
Докато insert()
методът е гъвкав, той е отхвърлен в много драйвери на MongoDB в полза на следните два метода.
Използване на insertOne()
метод
insertOne()
методът може да се използва за вмъкване на един документ. За разлика от insert()
метод, той може да вмъква само един документ наведнъж, което прави поведението му малко по-предвидимо.
Синтаксисът е същият като когато използвате insert()
за добавяне на един документ. Можем да добавим още един ученик на име Наоми:
db.students.insertOne( { first_name: "Naomi", last_name: "Pyani" })
{ "acknowledged" : true, "insertedId" : ObjectId("60e877914655cbf49ff7cb86")}
За разлика от insert()
, insertOne()
метод връща документ, съдържащ допълнителна полезна информация. Той потвърждава, че записът е бил потвърден от клъстера и включва идентификатора на обекта, който е бил присвоен на документа, тъй като не сме предоставили такъв.
Използване на insertMany()
метод
За да покриете сценарии, при които искате да вмъкнете няколко документа наведнъж, insertMany()
сега се препоръчва този метод. Точно както при вмъкване на множество документи с insert()
, insertMany()
приема масив от документи.
Можем да добавим трима нови ученици на име Жасмин, Майкъл и Тони:
db.students.insertMany( [ { first_name: "Jasmine", last_name: "Took", dob: new Date("April 11, 2011") }, { first_name: "Michael", last_name: "Rodgers", dob: new Date("February 25, 2008"), grade_level: 6 }, { first_name: "Toni", last_name: "Fowler" } ])
{ "acknowledged" : true, "insertedIds" : [ ObjectId("60e8792d4655cbf49ff7cb87"), ObjectId("60e8792d4655cbf49ff7cb88"), ObjectId("60e8792d4655cbf49ff7cb89") ]}
Както при insertOne()
, insertMany()
връща документ, който потвърждава записа и предоставя масив, съдържащ идентификаторите, които са били присвоени на вмъкнатите документи.
Как да направите заявка за съществуващи документи
Запитването на документи е доста обширна тема, която изисква собствена статия. Можете да намерите подробности за това как да формулирате заявки за извличане на различни типове документи в нашето ръководство за заявки за данни в MongoDB.
Въпреки че е най-добре да оставите подробностите в статията, свързана по-горе, можем поне да покрием методите, които MongoDB предоставя за заявка на документи. Основният начин за извличане на документи от MongoDB е чрез извикване на find()
метод за въпросната колекция.
Например, за да съберете всички документи от students
, можете да извикате find()
без аргументи:
db.students.find()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb85"), "first_name" : "Leah", "last_name" : "Drake", "dob" : ISODate("2009-10-03T00:00:00Z") }{ "_id" : ObjectId("60e877914655cbf49ff7cb86"), "first_name" : "Naomi", "last_name" : "Pyani" }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb87"), "first_name" : "Jasmine", "last_name" : "Took", "dob" : ISODate("2011-04-11T00:00:00Z") }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler" }
За да направите изхода по-четлив, можете също да верижите pretty()
метод след find()
:
db.<collection>.find().pretty()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8}{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2}{ "_id" : ObjectId("60e875d54655cbf49ff7cb85"), "first_name" : "Leah", "last_name" : "Drake", "dob" : ISODate("2009-10-03T00:00:00Z")}{ "_id" : ObjectId("60e877914655cbf49ff7cb86"), "first_name" : "Naomi", "last_name" : "Pyani"}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb87"), "first_name" : "Jasmine", "last_name" : "Took", "dob" : ISODate("2011-04-11T00:00:00Z")}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6}{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler"}
Можете да видите, че _id
полето е добавено към всеки от документите. MongoDB изисква уникален _id
за всеки документ в колекция. Ако не предоставите такъв при създаването на обект, той ще добави такъв вместо вас. Можете да използвате този идентификатор, за да извлечете надеждно един обект:
db.students.find( { _id : ObjectId("60e8792d4655cbf49ff7cb89") })
{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler" }
Можете да научите повече за различните начини за търсене на данни от статията, свързана по-горе.
Как да актуализирате съществуващи документи
Много или повечето случаи на използване на бази данни изискват от вас да можете да променяте съществуващи данни в базата данни. Може да се наложи да се актуализира поле, за да отрази нова стойност или може да се наложи да добавите допълнителна информация към съществуващ документ, когато стане наличен.
MongoDB използва няколко свързани метода за актуализиране на съществуващи документи:
updateOne()
:Актуализира един документ в колекция въз основа на предоставения филтър.updateMany()
:Актуализира множество документи в колекция, които съответстват на предоставения филтър.replaceOne()
:Заменя цял документ в колекция въз основа на предоставения филтър.
Ще разгледаме как да използвате всяка от тези разновидности за извършване на различни типове актуализации.
Оператори за актуализиране
Преди да разгледаме всеки от методите за актуализиране на документи, трябва да разгледаме някои от наличните оператори за актуализиране.
$currentDate
:Задава стойността на полето към текущата дата, като тип дата или време.- Синтаксис:
{ $currentDate: { <field>: <type>, ... } }
- Синтаксис:
$inc
:Увеличава стойността на поле със зададена сума.- Синтаксис:
{ $inc: { <field>: <amount>, ... } }
- Синтаксис:
$min
:Актуализира стойността на полето, ако посочената стойност е по-малка от текущата стойност.- Синтаксис:
{ $min: { <field>: <value>, ... } }
- Синтаксис:
$max
:Актуализира стойността на полето, ако посочената стойност е по-голяма от текущата стойност.- Синтаксис:
{ $max: { <field>: <value>, ... } }
- Синтаксис:
$mul
:Актуализира стойността на полето, като го умножи по даденото число.- Синтаксис:
{ $mul: { <field>: <value>, ... } }
- Синтаксис:
$rename
:Преименува име на поле на нов идентификатор.- Синтаксис:
{ $rename: { <field>: <new_name>, ... } }
- Синтаксис:
$set
:Заменя стойността на поле с дадената стойност.- Синтаксис:
{ $set: { <field>: value, ... } }
- Синтаксис:
$setOnInsert
:По време на операции на upsert, задава стойността на поле, ако се създава нов документ и не прави нищо по друг начин.- Синтаксис:
{ $setOnInsert: { <field>: <value>, ... } }
- Синтаксис:
$unset
:Премахва поле от документа.- Синтаксис:
{ $unset: { <field>: "", ... } }
- Синтаксис:
$
:Заместител за първия елемент на масива, който удовлетворява заявката.- Синтаксис:
{ <update_operator>: {<array>.$: <value> } }
- Синтаксис:
$[]
:Заместител за всички елементи на масива, които отговарят на заявката.- Синтаксис:
{ <update_operator>: { <array>.$[]: <value> } }
- Синтаксис:
$addToSet
:Добавя стойности към масива, освен ако вече не са налице.- Синтаксис:
{ $addToSet: { <field>: <value>, ... } }
- Синтаксис:
$pop
:Премахва първия или последния елемент от масива.- Синтаксис:
{ $pop: { <field>: (-1 or 1), ... } }
- Синтаксис:
$pull
:Премахва всички елементи от масив, които отговарят на условие.- Синтаксис:
{ $pull: { <field>: <condition>, ... } }
- Синтаксис:
$push
:Добавя стойност към масив.- Синтаксис:
{ $push: { <field>: <value>, ... } }
- Синтаксис:
$pullAll
:Премахва всички посочени елементи от масив.- Синтаксис:
{ $pullAll: { <field>: [ <value>, ... ], ...} }
- Синтаксис:
$each
:Променя$addToSet
и$push
оператори, така че да добавят всеки елемент от масив вместо масив като единичен елемент.- Синтаксис:
{ <update_operator>: { <field>: { $each: [ <value>, ... ] }, ... } }
- Синтаксис:
$position
:Използва се с$each
и определя позицията$push
оператор трябва да вмъкне at.- Синтаксис:
{ $push: { <field>: { $each: [ <value>, ... ], $position: <num> } } }
- Синтаксис:
$slice
:Използва се с$each
и$push
за да ограничите броя на общите елементи в масива.- Синтаксис:
{ $push: { <field>: { $each: [ <value>, ... ], $slice: <num> } } }
- Синтаксис:
$sort
:Използва се с$each
и$push
за сортиране на елементи от масива.- Синтаксис:
{ $push: { <field>: { $each: [ <value>, ... ], $sort: <sort_order> } } }
- Синтаксис:
Тези различни оператори за актуализиране ви позволяват да актуализирате различни полета на вашите документи по различни начини.
Актуализиране на един документ в колекция
updateOne()
на MongoDB методът се използва за актуализиране на един документ в рамките на колекция. Методът приема два задължителни аргумента, както и документ, посочващ незадължителни аргументи.
Първият аргумент е документ, който определя условията за филтриране, които ще бъдат използвани за избор на документи. Тъй като updateOne()
метод променя най-много един документ в колекция, ще се използва първият документ, който отговаря на условията на филтъра.
Вторият аргумент указва операцията за актуализиране, която трябва да се изпълни. Посочените по-горе операции за актуализиране могат да бъдат посочени тук, за да се промени съдържанието на съответстващия документ.
Третият аргумент е документ с различни опции за промяна на поведението на метода. Най-важните потенциални стойности са:
upsert
:Превръща операцията в процедура на upsert чрез вмъкване на нов документ, ако филтърът не съвпада с нито един съществуващ документ.collation
:Документ, който дефинира специфични за езика правила, които трябва да се прилагат за операцията.
Като пример можем да актуализираме един запис на ученик, който филтрираме по _id
поле, за да гарантираме, че насочваме към правилния документ. Можем да зададем grade_level
към нова стойност:
db.students.updateOne( { _id: ObjectId("60e8792d4655cbf49ff7cb89") }, { $set: { grade_level: 3 } })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
Актуализиране на множество документи в колекция
updateMany()
на MongoDB методът работи подобно на updateOne()
метод, но вместо това актуализира всеки документ, който съответства на дадения филтър, вместо да спира след първото съвпадение.
updateMany()
синтаксисът следва точно updateOne()
синтаксис, така че единствената разлика е обхватът на операцията.
Като пример, ако искаме да променим всички екземпляри на "composition" на "writing" в subjects
масив в нашите teachers
документи за събиране, бихме могли да използваме нещо подобно:
db.teachers.updateMany( { subject: "composition" }, { $set: { "subjects.$": "writing" } })
{ "acknowledged" : true, "matchedCount" : 3, "modifiedCount" : 3 }
Ако проверите документите, всеки екземпляр на "composition" трябваше да бъде заменен с "writing":
db.teachers.find()
{ "_id" : ObjectId("60eddca65eb74f5c676f3baa"), "first_name" : "Nancy", "last_name" : "Smith", "subjects" : [ "vocabulary", "pronunciation" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bab"), "first_name" : "Ronald", "last_name" : "Taft", "subjects" : [ "literature", "grammar", "writing" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bac"), "first_name" : "Casey", "last_name" : "Meyers", "subjects" : [ "literature", "writing", "grammar" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bad"), "first_name" : "Rebecca", "last_name" : "Carrie", "subjects" : [ "grammar", "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bae"), "first_name" : "Sophie", "last_name" : "Daggs", "subjects" : [ "literature", "writing", "grammar", "vocabulary", "pronunciation" ] }
Замяна на документ
replaceOne()
методът работи подобно на updateOne()
метод, но замества целия документ, вместо да актуализира отделни полета. Синтаксисът е същият като предишните две команди.
Например, ако Нанси Смит напусне вашето училище и я замените с учител на име Клара Нюман, който преподава литература, можете да напишете следното:
db.teachers.replaceOne( { $and: [ { first_name: "Nancy" }, { last_name: "Smith" } ] }, { first_name: "Clara", last_name: "Newman", subjects: [ "literature" ] })
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }
Можете да видите, че съответстващият документ е премахнат и че посоченият документ го е заменил:
db.teachers.find()
{ "_id" : ObjectId("60eddca65eb74f5c676f3baa"), "first_name" : "Clara", "last_name" : "Newman", "subjects" : [ "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bab"), "first_name" : "Ronald", "last_name" : "Taft", "subjects" : [ "literature", "grammar", "writing" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bac"), "first_name" : "Casey", "last_name" : "Meyers", "subjects" : [ "literature", "writing", "grammar" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bad"), "first_name" : "Rebecca", "last_name" : "Carrie", "subjects" : [ "grammar", "literature" ] }{ "_id" : ObjectId("60eddca65eb74f5c676f3bae"), "first_name" : "Sophie", "last_name" : "Daggs", "subjects" : [ "literature", "writing", "grammar", "vocabulary", "pronunciation" ] }
Как да изтрия документи
Премахването на документи от колекциите също е част от жизнения цикъл на документа. За да премахнете документ, можете да използвате deleteOne()
или deleteMany()
методи. Те имат един и същ синтаксис и се различават само по това колко документа работят.
В по-голямата си част всичко, което трябва да направите, за да изтриете документи с някой от тези методи, е да му предоставите филтърен документ, който указва как искате да изберете документа, който да бъде изтрит. deleteOne()
методът ще изтрие най-много един документ (независимо от това колко съвпадения създава филтърът), докато deleteMany()
метод изтрива всеки документ, който отговаря на условията на филтъра.
Например, за да изтриете един ученик, можете да предоставите _id
за да ги съпоставим изрично:
db.students.deleteOne({ _id: ObjectId("60e8792d4655cbf49ff7cb87")})
{ "acknowledged" : true, "deletedCount" : 1 }
Ако искаме да изтрием всеки ученик, който няма присвоено ниво на клас, можем да използваме deleteMany()
вместо това:
db.students.deleteMany({ grade_level: { $eq: null }})
{ "acknowledged" : true, "deletedCount" : 2 }
Ако проверим, трябва да видим, че всички останали ученици имат присвоено ниво на клас:
db.students.find()
{ "_id" : ObjectId("60e8743b4655cbf49ff7cb83"), "first_name" : "Ashley", "last_name" : "Jenkins", "dob" : ISODate("2003-01-08T00:00:00Z"), "grade_level" : 8 }{ "_id" : ObjectId("60e875d54655cbf49ff7cb84"), "first_name" : "Brian", "last_name" : "McMantis", "dob" : ISODate("2010-09-18T00:00:00Z"), "grade_level" : 2 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb88"), "first_name" : "Michael", "last_name" : "Rodgers", "dob" : ISODate("2008-02-25T00:00:00Z"), "grade_level" : 6 }{ "_id" : ObjectId("60e8792d4655cbf49ff7cb89"), "first_name" : "Toni", "last_name" : "Fowler", "grade_level" : 3 }
Заключение
Научаването как да създавате, заявявате, актуализирате и премахвате документи ви дава необходимите умения за ефективно управление на документи в MongoDB на дневна база. Запознаването с различните методи за документи и събиране и операторите, които ви позволяват да съпоставяте и променяте информация, ви позволява да изразявате сложни мисли, които системата на базата данни може да разбере.