Адкрыты вэбінар "Асновы MongoDB"

Сябры, чарговы запуск курса «Базы дадзеных» адбудзецца ўжо заўтра, таму мы правялі традыцыйны адкрыты ўрок, запіс якога вы можаце паглядзець тут. У гэты раз пагаварылі аб папулярнай БД MongoDB: вывучылі некаторыя тонкасці, разгледзелі асновы працы, магчымасці і архітэктуру. А таксама закранулі некаторыя User Cases.

Адкрыты вэбінар "Асновы MongoDB"

Вебінар правёў Іван Рэмень, кіраўнік кірунку сервернай распрацоўкі ў "Сіцімабіль".

Асаблівасці MongoDB

MongoDB - Дакументаарыентаваная СКБД з адкрытым зыходным кодам, якая не патрабуе апісання схемы табліц. Яна класіфікуецца як NoSQL і выкарыстоўвае BSON (бінарны JSON). Маштабуецца са скрынкі, напісана на мове C++ і падтрымлівае сінтаксіс JavaScript. Падтрымка SQL адсутнічае.

У MongoDB ёсць драйверы для шматлікіх папулярных моў праграмавання (Сі, C++, C#, Go, Java, JavaScript, Perl, PHP, Python, Ruby і інш.). Таксама ёсць неафіцыйныя і падтрымліваюцца супольнасцю драйверы для іншых моў праграмавання.

Што ж, давайце разгледзім асноўныя каманды, якія могуць быць карысныя.

Такім чынам, каб разгарнуць MongoDB у Docker, пішам:

docker run -it --rm -p 127.0.0.1:27017:27017 
--name mongo-exp-project mongo
docker exec -it mongo-exp-project mongo

Такім чынам, адбываецца запуск кліента MongoDB:

Адкрыты вэбінар "Асновы MongoDB"

А зараз напішам традыцыйны Прывітанне свет:

print (“Hello world!”)

Адкрыты вэбінар "Асновы MongoDB"

Пасля гэтага - запусцім цыкл:

Адкрыты вэбінар "Асновы MongoDB"

Як вы заўважылі, перад намі звычайны JS, а MongoDB - гэта паўнавартасны інтэрпрэтатар JavaScript.

Калі прымяняць MongoDB?

Ёсць байка аб тым, што сярэдні стартапер у крамянёвай даліне - гэта чалавек, які тыдзень таму адкрыў кніжку "HTML для чайнікаў". Які ён выбера стэк? Пагодзіцеся, што яму вельмі зручна, калі ў яго ў браўзэры па відавочных чынніках знаходзіцца JavaScript, на серверы круціцца Node.js, а ў базе дадзеных таксама JavaScript. Гэта момант №1.

Па-другое, ёсць выдатны выступ Пятра Зайцава, аднаго з лепшых спецыялістаў па базах даных у Расіі. У ім Пётр распавядае пра MySQL і MongoDB, надаючы асаблівую ўвагу таму, калі і што лепш выкарыстоўваць.

Па-трэцяе, жадаецца падкрэсліць, што MongoDB характарызуецца добрай маштабаванасцю - і гэта адна з ключавых асаблівасцяў БД. Калі вы загадзя не ведаеце, якая будзе нагрузка, MongoDB выдатна падыдзе. Да таго ж, яна падтрымлівае такія патэрны са скрынкі, як шадзіраванне и рэплікацыя, і ўсё гэта зроблена дастаткова празрыстым, гэта значыць працаваць вельмі зручна.

Што тычыцца тэрміналогіі у MongoDB, то:

  • базы - гэта базы (схемы, сукупнасць табліц);
  • у MongoDB ёсць такое паняцце, як калекцыя - Гэта аналаг табліцы і набор дакументаў, якія па логіцы рэчаў павінны быць звязаны;
  • дакументы - гэта аналаг радка.

Стварэнне базы дадзеных і простыя запыты

Каб стварыць базу дадзеных, трэба проста пачаць яе выкарыстоўваць:

use learn

Адкрыты вэбінар "Асновы MongoDB"

Цяпер зробім невялікую ўставачку дакумента. Няхай гэта будзе, напрыклад, аднарог з імем Аўрора:

db.unicorns.insert({name: 'Aurora', gender: 'f', weight: 450})

db - Глабальны аб'ект для доступу да БД, гэта значыць, па сутнасці, сама «монга». Для шардынгу выкарыстоўваецца sh, для рэплікацыі rs.

Якія каманды ёсць у аб'екта db:

Адкрыты вэбінар "Асновы MongoDB"

Такім чынам, вернемся да нашай каманды, у выніку прымянення якой кансоль паведаміць, што ўстаўлены адзін радок:

Адкрыты вэбінар "Асновы MongoDB"

Слова unicorns у камандзе db.unicorns.insert({name: 'Aurora', gender: 'f', weight: 450}) абазначае калекцыю. Тут звернеце ўвагу, што мы калекцыю не апісвалі і не стваралі, а проста напісалі 'unicorns', зрабілі insert, і ў нас з'явілася калекцыя.

А вось так мы зможам атрымаць усе нашы калекцыі:

db.getCollectionNames()

Ну і гэтак далей. Можам ўставіць яшчэ адну калекцыю:

Адкрыты вэбінар "Асновы MongoDB"

А зараз запытаем поўную калекцыю (нагадваем, што ў нашым выпадку ў базе дадзеных ужо знаходзіцца інфармацыя аб двух аднарогах з аднолькавым імем):

db.unicorns.find()

Звярніце ўвагу, вось і наш JSON (ёсць імя, падлога, вага, нейкі ўнікальны ідэнтыфікатар аб'екта):

Адкрыты вэбінар "Асновы MongoDB"

Цяпер давайце ўставім яшчэ парачку аднарогаў з аднолькавымі імёнамі:

db.unicorns.insert({name: 'Leto', gender: 'm', 
home: 'Arrakeen', worm: false}) 
db.unicorns.insert({name: 'Leto', gender: 'm', 
home: 'Arrakeen', worm: false})

І паглядзім, што атрымалася:

Адкрыты вэбінар "Асновы MongoDB"

Як бачыце, у нас з'явіліся дадатковыя палі: дадому и чарвяк, якіх няма ў Аўроры.

Дадамо яшчэ некалькі аднарогаў:

db.unicorns.insertMany([{name: 'Horny', dob: new Date(1992,2,13,7,47), loves: ['carrot','papaya'], weight: 600, gender: 'm', vampires: 63}, 
{name: 'Aurora', dob: new Date(1991, 0, 24, 13, 0), loves: ['carrot', 'grape'], weight: 450, gender: 'f', vampires: 43}, 
{name: 'Unicrom', dob: new Date(1973, 1, 9, 22, 10), loves: ['energon', 'redbull'], weight: 984, gender: 'm', vampires: 182}, 
{name: 'Roooooodles', dob: new Date(1979, 7, 18, 18, 44), loves: ['apple'], weight: 575, gender: 'm', vampires: 99}])

Такім чынам, мы ўставілі з дапамогай JavaScript яшчэ чатыры аб'екты:

Адкрыты вэбінар "Асновы MongoDB"

Як вы думаеце, у якіх БД зручней захоўваць пашпартныя дадзеныя: у рэляцыйных БД ці ў монге?

Адказ відавочны - у монге, і вышэйапісаны прыклад добра гэта паказвае. Не сакрэт, што Кладр - гэта боль у РФ. А монга вельмі добрае кладзецца на адрасы, бо можна задаць усё як масіў, і будзе значна прасцей жыць. І гэта добры User Case для MongoDB.

Дадамо яшчэ аднарогаў:

db.unicorns.insert({name: 'Solnara', dob: new Date(1985, 6, 4, 2, 1), loves:['apple', 'carrot', 'chocolate'], weight:550, gender:'f', vampires:80}); 
db.unicorns.insert({name:'Ayna', dob: new Date(1998, 2, 7, 8, 30), loves: ['strawberry', 'lemon'], weight: 733, gender: 'f', vampires: 40}); 
db.unicorns.insert({name:'Kenny', dob: new Date(1997, 6, 1, 10, 42), loves: ['grape', 'lemon'], weight: 690, gender: 'm', vampires: 39}); 
db.unicorns.insert({name: 'Raleigh', dob: new Date(2005, 4, 3, 0, 57), loves: ['apple', 'sugar'], weight: 421, gender: 'm', vampires: 2}); 
db.unicorns.insert({name: 'Leia', dob: new Date(2001, 9, 8, 14, 53), loves: ['apple', 'watermelon'], weight: 601, gender: 'f', vampires: 33}); 
db.unicorns.insert({name: 'Pilot', dob: new Date(1997, 2, 1, 5, 3), loves: ['apple', 'watermelon'], weight: 650, gender: 'm', vampires: 54}); 
db.unicorns.insert({name: 'Nimue', dob: new Date(1999, 11, 20, 16, 15), loves: ['grape', 'carrot'], weight: 540, gender: 'f'}); 
db.unicorns.insert({name: 'Dunx', dob: new Date(1976, 6, 18, 18, 18), loves: ['grape', 'watermelon'], weight: 704, gender: 'm', vampires: 165});

Адкрыты вэбінар "Асновы MongoDB"

А зараз звернеце ўвагу на дакументы. Ў якасці добра у нас захоўваюцца цэлыя аб'екты. А яшчэ ёсць інфармацыя аб тым, што любіць аднарог, прычым гэтыя дадзеныя ёсць не ва ўсіх. Такім чынам, усярэдзіне ляжыць паўнавартасны масіў.

Дарэчы, для прыгажэйшай высновы вынікаў, можна ў канцы каманды пошуку выклікаць метад .pretty():

Адкрыты вэбінар "Асновы MongoDB"

Калі трэба атрымаць інфармацыю аб апошняй памылцы, выкарыстоўваем наступную каманду:

db.getLastError()

Гэта можна рабіць пасля кожнай устаўкі, альбо наладзіць Write Concern. Лепш пачытаць пра гэта ў афіцыйнай дакументацыі, якая, дарэчы, у монге вельмі змястоўная. Дарэчы, на хабры таксама ёсць нядрэнны артыкул з гэтай нагоды.

Пераходзім да больш складаных запытаў

Запыт па дакладным значэнні поля:

db.unicorns.find({gender: 'm'})

Напісаўшы такі запыт, мы атрымаем у выснове на кансолі спіс усіх аднарогаў-мужчын.

Таксама можна выканаць запыт адразу па некалькіх палях: па падлозе і па вазе:

Адкрыты вэбінар "Асновы MongoDB"

Вышэй звернеце ўвагу на спецыяльны селектар $gt, Які дазваляе вывесці ўсіх аднарогаў мужчынскага полу вагой больш за 700

Можна праверыць, ці існуе поле наогул:

db.unicorns.find({vampires: {$exists: false}})

Або так:

db.unicorns.find({'parents.father': {$exists: true}})

Наступная каманда выведзе аднарогаў, імёны якіх пачынаюцца з літар А ці а:

db.unicorns.find({name: {$regex: "^[Aa]"}})

Цяпер разгледзім пошук па масіве. Пытанне № 1: што выведзе гэтая каманда:

db.unicorns.find({loves:'apple'})

Правільна: усіх, хто любіць яблыкі.

Наступная каманда верне толькі тыя дадзеныя аб аднарогу, у якіх змяшчаюцца толькі яблыкі і кавуны:

db.unicorns.find({loves:[ "apple", "watermelon" ]})

І яшчэ адна каманда:

db.unicorns.find({loves:[ "watermelon", "apple" ]})

У нашым выпадку яна нічога не верне, бо, калі мы перадаем масіў, параўноўваецца першы элемент з першым, другі з другім і т. д. Гэта значыць масіў павінен супадаць яшчэ і па пазіцыях гэтых значэнняў.

А вось так выглядае пошук па масіве з выкарыстаннем аператара «АБО»:

Адкрыты вэбінар "Асновы MongoDB"

Наступны прыклад прадэманструе нам пошук з выкарыстаннем аператара $all. І тут ужо паслядоўнасць непрынцыповая:

Адкрыты вэбінар "Асновы MongoDB"

Таксама мы можам шукаць і па памеры масіва:

Адкрыты вэбінар "Асновы MongoDB"

А што рабіць, калі мы хочам знайсці масіў, у якога памер больш за адзінку? Для гэтага існуе аператар $where, з дапамогай якога можна пісаць больш складаныя рэчы:

db.unicorns.find({$where: function() { return this.loves && (this.loves.length > 1) } })

Дарэчы, калі хочаце папрактыкавацца, вось вам файлік з камандамі.

Асаблівасці курсора

Трохі адцягнемся і скажам пару слоў пра асаблівасці монгі:

  • find() і іншыя аперацыі не вяртаюць дадзеныя - яны вяртаюць так званы "курсор";
  • тое, што мы бачым, як дадзеныя друкуюцца, ёсць праца інтэрпрэтатара.

Набраўшы db.unicorns.find без дужак, мы атрымаем падказку:

Адкрыты вэбінар "Асновы MongoDB"

Працягваем выконваць запыты

Ёсць яшчэ аператар $in:

db.unicorns.find({weight: {$in: [650, 704]}})

Адкрыты вэбінар "Асновы MongoDB"

Цяпер пагаворым пра update. Напрыклад, давайце зменім вагу аднарога Roooooodles:

db.unicorns.update({name: "Roooooodles"}, {weight: 2222})

У выніку нашых дзеянняў дакумент цалкам абновіцца, а ў ім застанецца толькі адно азначанае поле:

Адкрыты вэбінар "Асновы MongoDB"

Гэта значыць адзінае, што застанецца ў нашага аб'екта - гэта вага 2222 і, зразумела, id.

Выправіць сітуацыю можна з дапамогай $набор:

db.unicorns.update({_id: ObjectId("5da6ea4d9703b8be0089e6db")}, {$set: { "name" : "Roooooodles", "dob" : ISODate("1979-08-18T18:44:00Z"), "loves" : [ "apple" ], "gender" : "m", "vampires" : 99}})

Адкрыты вэбінар "Асновы MongoDB"

Таксама ёсць магчымасць інкрыментаваць значэння:

Адкрыты вэбінар "Асновы MongoDB"

А яшчэ ёсць upsert - камбінацыя update і insert:

Адкрыты вэбінар "Асновы MongoDB"

А вось як здзяйсняецца выбарка палёў:

Адкрыты вэбінар "Асновы MongoDB"

Адкрыты вэбінар "Асновы MongoDB"

Застаецца дадаць пару слоў пра прапускаць и мяжа:

Адкрыты вэбінар "Асновы MongoDB"

Калегі, на гэтым усё, калі хочаце даведацца падрабязнасці, глядзіце відэа цалкам. І не забывайце пакідаць свае каментары!

Крыніца: habr.com

Дадаць каментар