MongoDB: Introduction,Robomongo,CRUD


MongoDB official site
MongoDB вводная лекция
Вторая лекция по mongoDB — CRUD
MongoDB Aggregation Framework
MongoDB: обзор основных возможностей
MongoDB — Олег Мохов
Слайд презентации MongoDB — Олег Мохов
mongo shell

Introduction

MongoDB — не реляционная, документо-ориентированная база данных. База состоит из колекций, каждая из которых представляет собой BSON документ не имеющий чёткой структуры (т. е. каждый документ может содержать своё кол-во полей), что является как преимуществом так и недостатком.
Шаблон коллекции:

//Коллекция
    //Документ1
{
    "key1":"value1", //поле1
    "key2":num1, //поле2
    "key3":[1,2,3], //поле3
    "key4":{key:val,key:val,key:val}, //поле4
    ...
}
    //Документ2
{
    "key1":"value2",
    "key2":num2,
    "key3":[3,4,5],
    "key4":{key:val,key:val,key:val},
    ...
}

где ключ — может быть только строкой, а значение — любой тип данных.
Для лучшего понимания нужно ознакомиться с структорой JSON документа.

Запускаем mongo сервер в контейнере

Создаём том для баз mongo
docker volume  create mongodb_vol

Запускаем контейнер
docker container run \
-d \
--restart=always \
--name mongodb \
-p 27017:27017 \
-e MONGO_INITDB_ROOT_USERNAME="admin" \
-e MONGO_INITDB_ROOT_PASSWORD="adminpass" \
-v mongodb_vol:/data/db \
mongo

Подключение к mongodb

Подключиться к серверу можно несколькими способами:

container mongo shell

1. Используя mongo шел самого контейнера

docker container exec -it \
mongodb mongo -u 'admin' -p 'adminpass' \
--authenticationDatabase admin

mongo shell from OS repo

2. установить mongo шел из репозитория вашей ОС

Установка mongo шела
Ubuntu
aptitude install mongodb-clients
CentOS
yum install mongodb-clients

Подключение к серверу с хостовой тачки:
mongo -u 'admin' -p 'adminpass' --authenticationDatabase admin

mongo shell from off-site

3. скачать архив с официального сайта mongoDB, который содержит в том числе и бинарник шела
и затем запускать этот шел либо из папки куда разархивировали содержимое
либо перекопировать бинарный файл в директорию/usr/bin

cd mongodb-linux-x86_64-ubuntu1604-4.0.0/bin
./mongo -u 'admin' -p 'adminpass' --authenticationDatabase admin

Robomongo

Robomongo — это графический интерфейс (GUI) для mongoDB.
Чтоб его установить необходимо:
1. пройти на сайт robomongo.org
2. скачать архив под вашу ОС (в моём случае это Linux)
3. разархивировать
4. перейти в директорию и запустить robo3t

tar zxvf robo3t-1.2.1-linux-x86_64-3e50a65.tar.gz
cd robo3t-1.2.1-linux-x86_64-3e50a65
./bin/robo3t

После запуска нам предлагается создать подключение к mongo сервису

Нажимаем Create

Заполняем поля
Type — оставляем Direct Connection
Name — любое понравившееся название,например DockerMongoDB
Address — оставляем localhost:27017

Далее переходим во вкладку Authentication
Активируем поля выставив галочку в поле Perform authentication
Остальные поля заполняем так:
Database: admin
UserName: admin
Password: adminpass
Auth Mechanism: SCRAM-SHA-1

Для проверки соединения нажимаем Test и если всё хорошо, то должны увидеть что то похожее

Далее нажимаем Close->Save->Connect и при успешном подключении видим доступные базы

CRUD

расшифровывается как:
create — insert()
read — find()
update — update()
delete — remove()

show dbs — показать список баз
use [DATA_BASE_NAME] — создание,переключение баз данных
db.getName() или просто db — узнать имя базы которая используется сейчас
show collections — показать список коллекций в базе
db.[COLLECTION].drop() — удалить коллекцию
db.dropDatabase() — удаление базы данных

Вставка документов

Рассмотрим несколько примеров вставки документов в базу:

Method insert()

1. через mongo шел методом insert()

use ипользуется для переключения между базами, но если базы не существует то база будет создана 
при создании коллекции в этой базе
use corpdb

Добавим данные в коллекцию staffcoll (коллекция создается автоматически при добвалении в нее данных)
db.staffcoll.insert({name:"Alex",email:"alex@email.com",age:19,dep:"dev"})
db.staffcoll.insert({name:"Malex",email:"malex@email.com",age:25,dep:"dev"})
db.staffcoll.insert({name:"Dima",email:"dima@email.com",age:25,dep:"dev"})
db.staffcoll.insert({name:"Sergey",email:"sergey@email.com",age:20,dep:"dev"})
db.staffcoll.insert({name:"Roma",email:"roma@email.com",age:25,dep:"dev"})
db.staffcoll.insert({name:"Maria",email:"maria@email.com",age:35,dep:"buh"})
db.staffcoll.insert({name:"Ola",email:"ola@email.com",age:27,dep:"buh"})
db.staffcoll.insert({name:"Oleg",email:"oleg@email.com",age:23,dep:"admin"})

JavaScript Functions

2. через js скрипт, т.к. mongo использует js то на ходу можно писать свои фун-ии
Добавим еще одну коллекцию в базу.
Пусть у нас имеется такой набор документов:

var company_assets = [{
  assetId:1,
  item:"MacBook",
  state:"In Use",
  ownerEmail:"roma@email.com", 
  loc:"dev"
},{
  assetId:2,
  item:"iPhone",
  state:"Free",
  ownerEmail:"", 
  loc:"storage"
},{
  assetId: 3,
  item:"Tab",
  state: "In Use",
  ownerEmail: "dima@email.com", 
  loc: "dev"
},{
  assetId: 4,
  item:"NoteBook",
  state: "In Use",
  ownerEmail: "oleg@email.com", 
  loc: "admin"
}]

И такая фун-ия:

function db_add(myarray){
    for (var i=0;i <= myarray.length;i++){
        db.assetscoll.insert({assetId:myarray[i].assetId,
        item:myarray[i].item,
        state:myarray[i].state,
        ownerEmail:myarray[i].ownerEmail,
        loc:myarray[i].loc,})
    }
}

Добавим переменную company_assets и фун-ию db_add в mongo консоль.
Вызовем нашу фун-ию и передадим в неё переменную db_add(company_assets)
Смотрим, что коллекция появилась

> show collections
assetscoll
staffcoll

Смотрим, что данные добавились

db.assetscoll.find()
{ "_id" : ObjectId("5b515bd60dc6ea027cff065f"), "assetId" : 1, "item" : "MacBook", "state" : "In Use", "ownerEmail" : "roma@email.com", "loc" : "dev" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0660"), "assetId" : 2, "item" : "iPhone", "state" : "Free", "ownerEmail" : "", "loc" : "storage" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0661"), "assetId" : 3, "item" : "Tab", "state" : "In Use", "ownerEmail" : "dima@email.com", "loc" : "dev" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0662"), "assetId" : 4, "item" : "NoteBook", "state" : "In Use", "ownerEmail" : "oleg@email.com", "loc" : "admin" }

mongoimport

3. через утилиту mongoimport
mongoimport -d[DB_NAME] -c[NAME_COLLECTION] < [JSONFILE] — импорт данных из json файла в коллекцию
DB_NAME — имя базы
NAME_COLLECTION — имя коллекции
JSONFILE — имя json файла который планируется импортировать

На просторах Интернета находим случайный json файл и скачиваем его
curl -O https://support.oneskyapp.com/hc/en-us/article_attachments/202761727/example_2.json

Копируем в контейнер
docker container cp ./example_2.json mongodb:/root

Заходим в шел контейнера, переходим в нужную директорию
docker container exec -it mongodb bash
cd /root

Импортируем данные с json файла в новую коллекцию examplecoll
mongoimport -u 'admin' -p 'adminpass' --authenticationDatabase admin -d corpdb -c examplecoll < example_2.json Смотрим появилась ли коллекция >show collections
assetscoll
examplecoll
staffcoll

Просматриваем импортированные данные
db.examplecoll.find().pretty()

Выборка документов

Выборка данных происходит с помощью метода find()

find()

db.[COLLECTION_NAME].find() — показать все записи в коллекции
db.[COLLECTION_NAME].find().pretty() — показать все записи в коллекции, как json документ
db.[COLLECTION_NAME].find().count() — получит кол-во найденых документов в коллекции по заданному селектору
db.[COLLECTION_NAME].find().limit([LIMIT_NUM]) — ограничить вывод результата на экран

Выведим данные из коллекции assetscoll
> db.assetscoll.find()
{ "_id" : ObjectId("5b515bd60dc6ea027cff065f"), "assetId" : 1, "item" : "MacBook", "state" : "In Use", "ownerEmail" : "roma@email.com", "loc" : "dev" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0660"), "assetId" : 2, "item" : "iPhone", "state" : "Free", "ownerEmail" : "", "loc" : "storage" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0661"), "assetId" : 3, "item" : "Tab", "state" : "In Use", "ownerEmail" : "dima@email.com", "loc" : "dev" }
{ "_id" : ObjectId("5b515bd60dc6ea027cff0662"), "assetId" : 4, "item" : "NoteBook", "state" : "In Use", "ownerEmail" : "oleg@email.com", "loc" : "admin" }

> db.assetscoll.find().pretty()
{
	"_id" : ObjectId("5b515bd60dc6ea027cff065f"),
	"assetId" : 1,
	"item" : "MacBook",
	"state" : "In Use",
	"ownerEmail" : "roma@email.com",
	"loc" : "dev"
}
{
	"_id" : ObjectId("5b515bd60dc6ea027cff0660"),
	"assetId" : 2,
	"item" : "iPhone",
	"state" : "Free",
	"ownerEmail" : "",
	"loc" : "storage"
}
{
	"_id" : ObjectId("5b515bd60dc6ea027cff0661"),
	"assetId" : 3,
	"item" : "Tab",
	"state" : "In Use",
	"ownerEmail" : "dima@email.com",
	"loc" : "dev"
}
{
	"_id" : ObjectId("5b515bd60dc6ea027cff0662"),
	"assetId" : 4,
	"item" : "NoteBook",
	"state" : "In Use",
	"ownerEmail" : "oleg@email.com",
	"loc" : "admin"
}

Если коллекция слишком большая и весь список данных не влазит в один вывод экрана, то пролистать его можно с помощью команды it

ObjectID

Как мы видим из примера, mongo автоматически добавляет поле _id — не случайная уникальная последовательность
Рассмотрим пример такой последовательности 5b4edf36bd575d1b29145aaf, она состоит из:
4 bytes 5b4edf36 — timestamp, кол-во секунд с полуночи (00:00:00 UTC) 1 января 1970 года (см. Unix Epoch)
3 bytes bd575d — mid идентификатор машины
2 bytes 1b29 — pid идентификаатор процесса
3 bytes 145aaf — просто счетчик, перое число выбирается случайно

find({selector1,selector2,…},{fields})

find имеет широкий арсенал поиска/фильтрации данных по коллекции
db.[COLLECTION_NAME].find({selector1,selector2,...},{fields}) — выборка/поиск данных по селектору/селекторам и полям фильтрации
selector — селектор представляющий собой поле и его значение по которому хотим осуществить поиск в коллекции
fields — поля которые хотим добавить или скрыть

Показать всех сотрудников в возрасте 25 лет, показать все поля
db.staffcoll.find({age:25})
{ "_id" : ObjectId("5b514ab70dc6ea027cff064c"), "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064d"), "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064f"), "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }

Найти сотрудника с именем Alex в возрасте 19 лет
db.staffcoll.find({name:"Alex",age:19})
{ "_id" : ObjectId("5b514ab70dc6ea027cff064b"), "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }

Показать всех сотрудников в возрасте 25 лет, не показывать поля _id и age 
db.staffcoll.find({age:25},{_id:0,age:0}) 
{ "name" : "Malex", "email" : "malex@email.com", "dep" : "dev" } 
{ "name" : "Dima", "email" : "dima@email.com", "dep" : "dev" } 
{ "name" : "Roma", "email" : "roma@email.com", "dep" : "dev" } 

Показать всех сотрудников в возрасте 25 лет, показать только name и dep
db.staffcoll.find({age:25},{_id:0,name:1,dep:1}) 
{ "name" : "Malex", "dep" : "dev" } 
{ "name" : "Dima", "dep" : "dev" } 
{ "name" : "Roma", "dep" : "dev" }

find() and Comparison Operators — $lt,$gt,$lte,$gte

При задании селектора могут быть использованы различные логические операторы, операторы сравнения и т.д.
db.[COLLECTION_NAME].find({[FIELD_NAME]: {[QUERY] : [VALUE]}}) — общий вид команды с использованием операторов сравнения
Где [QUERY] может принимать значение операторов сравнения

Не полный список операторов сравнения:
$ne не равно
$lt < 
$gt >
$lte <= 
$gte >=
Поиск сотрудникоа в возрасте 25 лет и старше
db.staffcoll.find({age:{$gte:25}})
{ "_id" : ObjectId("5b514ab70dc6ea027cff064c"), "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064d"), "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064f"), "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0650"), "name" : "Maria", "email" : "maria@email.com", "age" : 35, "dep" : "buh" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0651"), "name" : "Ola", "email" : "ola@email.com", "age" : 27, "dep" : "buh" }

Поиск сотрудникоа старше 25 лет но моложе 30
db.staffcoll.find({age:{$gt:25,$lt:30}})
{ "_id" : ObjectId("5b514ab70dc6ea027cff0651"), "name" : "Ola", "email" : "ola@email.com", "age" : 27, "dep" : "buh" }

find() and Logical Operators — $or,$and,$nor,$not

db.[COLLECTION_NAME].find({[QUERY]:[{[FIELD_NAME]:[VALUE]},{[FIELD_NAME]:[VALUE]}]}) — общий вид команды с использованием логических операторов
Где [QUERY] может быть:

$or или
$and и
$nor не или
$not не
Показать список сотрудников отделов dev ИЛИ admin
db.staffcoll.find({$or:[{dep:"dev"},{dep:"admin"}]},{_id:0})
{ "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }
{ "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
{ "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "name" : "Sergey", "email" : "sergey@email.com", "age" : 20, "dep" : "dev" }
{ "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }
{ "name" : "Oleg", "email" : "oleg@email.com", "age" : 23, "dep" : "admin" }

Показать список сотрудников отдела dev И в возрасте 25 лет 
db.staffcoll.find({$and:[{dep:"dev"},{age:25}]},{_id:0}) 
{ "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" } 
{ "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" } 
Про $and нужно отметить, что данный опертар имеет более короткий и уже привычный синтаксис. 
Т.е. предыдущий запрос эквивалентен: 
db.staffcoll.find({dep:"dev",age:25},{_id:0}) 
{ "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" } 
{ "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" } 
{ "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }

find() and Regular Expression — $regex

В селекторах могу быть использованы регулярные выражения, синтаксис их использования может иметь два вида с $regex и без.
db.[COLLECTION_NAME].find({[FIELD]: {$regex:/[REGEX]/,$options: ''}})
db.[COLLECTION_NAME].find({[FIELD]: /[PATTERN]/<options>})

Найти сотрудников в именах, которых есть 'lex', патерн поиска задаем заглавными буквами,
но с использование опции игнорирования регистра
db.staffcoll.find({name: /LEX/i})
{ "_id" : ObjectId("5b514ab70dc6ea027cff064b"), "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064c"), "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }

find() and operator $exist

Если необходимо найти документы содержащии или не содержащии определенное поле,
то используется оператор $exists
db.[COLLECTION_NAME].find({[FIELD]: {$exist:true/false}}) поиск докумантов с определенным полем или без

Показать документы с полем dep
db.staffcoll.find( { dep: { $exists: true } } )
{ "_id" : ObjectId("5b514ab70dc6ea027cff064b"), "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064c"), "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064d"), "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064e"), "name" : "Sergey", "email" : "sergey@email.com", "age" : 20, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064f"), "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0650"), "name" : "Maria", "email" : "maria@email.com", "age" : 35, "dep" : "buh" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0651"), "name" : "Ola", "email" : "ola@email.com", "age" : 27, "dep" : "buh" }
{ "_id" : ObjectId("5b514ab80dc6ea027cff0652"), "name" : "Oleg", "email" : "oleg@email.com", "age" : 23, "dep" : "admin" }

Показать документы с полем status
> db.staffcoll.find( { status: { $exists: true } } )
> 

find() and operator $type

Если необходимо найти документы содержащии поле с определенным типом данных,
то используется оператор $type
db.[COLLECTION_NAME].find({[FIELD]: {$type:[TYPE]}}) поиск докумантов с данными определенного типа
где TYPE принимает числовые значения типов:

Не полный список
Double 	1
String 	2
Object 	3
32-bit integer 	16
Поиск документов в которых поле age содержит double тип данных
db.staffcoll.find({age:{$type:1}})
{ "_id" : ObjectId("5b514ab70dc6ea027cff064b"), "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064c"), "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064d"), "name" : "Dima", "email" : "dima@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064e"), "name" : "Sergey", "email" : "sergey@email.com", "age" : 20, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff064f"), "name" : "Roma", "email" : "roma@email.com", "age" : 25, "dep" : "dev" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0650"), "name" : "Maria", "email" : "maria@email.com", "age" : 35, "dep" : "buh" }
{ "_id" : ObjectId("5b514ab70dc6ea027cff0651"), "name" : "Ola", "email" : "ola@email.com", "age" : 27, "dep" : "buh" }
{ "_id" : ObjectId("5b514ab80dc6ea027cff0652"), "name" : "Oleg", "email" : "oleg@email.com", "age" : 23, "dep" : "admin" }

find() and operators $all,$in,$nin

Для поиска документов содержащих определенные данные в массивах используются операторы $all,$in,$nin
Операторы:

$all соответсвие всем эл-ам массива
$in соответсвие хотябы одному эл-у массива
$nin соответсвие ни одному эл-у массива

Общий синтаксис команд:

db.[COLLECTION_NAME].find({[FIELD]:{$in:[SUB_ARRAY]}})
db.[COLLECTION_NAME].find({[FIELD]:{$all:[SUB_ARRAY]}})
db.[COLLECTION_NAME].find({[FIELD]:{$nin:[SUB_ARRAY]}})

Рассмотрим примеры

Предварительно добавим новую коллекцию машин
db.cars.insert({company:"Toyota",models:["Corolla","Camry","RAV4","Alleon","Allex"]})
db.cars.insert({company:"Nissan",models:["Juke","Note","Teana","Cube","Safari"]})
db.cars.insert({company:"Honda",models:["Fit","Accord","Civic","Life","Inetgra"]})
db.cars.insert({company:"Mitsubishi",models:["Outlander","Lancer","Pajero","Delica","Airtrek"]})
db.cars.insert({company:"Subaru",models:["Forester","Impreza","Legacy","Outback","R2"]})

Поиск документов содеражщих любой из эл-ов в массиве поиска
> db.cars.find({models:{$in:["Corolla","Civic","Escudo","Jimny"]}})
{ "_id" : ObjectId("5b55641f32c1d0ab79c64f11"), "company" : "Toyota", "models" : [ "Corolla", "Camry", "RAV4", "Alleon", "Allex" ] }
{ "_id" : ObjectId("5b55641f32c1d0ab79c64f13"), "company" : "Honda", "models" : [ "Fit", "Accord", "Civic", "Life", "Inetgra" ] }

Поиск документов содеражщих все эл-ты в массиве поиска
> db.cars.find({models:{$all:["Corolla","Prius","Crown","Altezza"]}})
> 
Как видим ни одного соответствия не найдено
Теперь попробуем такой вариант:
> db.cars.find({models:{$all:["Forester","Impreza","Legacy"]}})
{ "_id" : ObjectId("5b55642132c1d0ab79c64f15"), "company" : "Subaru", "models" : [ "Forester", "Impreza", "Legacy", "Outback", "R2" ] }
Документ найден.

Теперь найдём документы в которых нет ни одного из эл-ов переданных в массиве поиска
> db.cars.find({models:{$nin:["Corolla","Civic","Juke"]}})
{ "_id" : ObjectId("5b55641f32c1d0ab79c64f14"), "company" : "Mitsubishi", "models" : [ "Outlander", "Lancer", "Pajero", "Delica", "Airtrek" ] }
{ "_id" : ObjectId("5b55642132c1d0ab79c64f15"), "company" : "Subaru", "models" : [ "Forester", "Impreza", "Legacy", "Outback", "R2" ] }

db.[COLLECTION_NAME].find({"object.property":value}) — поиск документов в полях содержащих js объекты

Обновление данных

Обновление отдельных полей документа, всего документа,нескольких документов или всей коллекции происходит с помощью метода update()
db.[COLLECTION].update({selector},{update},{options})
метод update принимает три аргумента:
1. селектор по которому будет осущетвлен поиск документов
2. параметры обновления
3. доп. флаги upsert,multi,writeConcern,collation,arrayFilters

Модифицируем весь документ

db.[COLLECTION].update({selector},{[FIELD]:[VALUE],[FIELD]:[VALUE]...},{options}) — обновить весь документ

У нас имеется документ 
db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Corolla", "Camry", "RAV4", "Alleon", "Allex" ] }

Обновим весь документ с Toyota
db.cars.update({company:"Toyota"},{company:"Toyota",models:["Celica","Belta","Ist"]})
Данная команда перезапишет весь документ, поэтому в параметрах обновления нужно указывать все поля документа.

Проверяем
db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Belta", "Ist" ] }

upsert

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

Смотрим, что данный селектор ничего не находит
> db.staffcoll.find({name:"Palex"})
>
Добавляем документ
> db.staffcoll.update({name:"Palex"},{"name" : "Palex", "email" : "palex@email.com", "age" : 37, "dep" : "dev"},{upsert:1})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.staffcoll.find({name:"Palex"})
{ "_id" : ObjectId("5b56bf6d23095fd66a32cbeb"), "name" : "Palex", "email" : "palex@email.com", "age" : 37, "dep" : "dev" }

Модифицируем отдельное поле документа — $inc,$set,$unset,$rename

метод update() сожержит различные операторы, которые помогают модифицировать отдельные поля, массивы данных, например такие операторы как $inc,$set,$unset,$rename,$min,$max

$set,$unset

db.[COLLECTION].update({selector},{$set:{[FIELD]:[VALUE]}}) — изменить/добавить поле
db.[COLLECTION].update({selector},{$unset:{[FIELD]:""}}) — удалить поле

Модифицируем следующий документ
> db.staffcoll.find({name:"Alex"},{_id:0})
{ "name" : "Alex", "email" : "alex@email.com", "age" : 19, "dep" : "dev" }
Сменим значение поля email
db.staffcoll.update({name:"Alex"},{$set:{email:"alexxx@email.org"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.staffcoll.find({name:"Alex"},{_id:0})
{ "name" : "Alex", "email" : "alexxx@email.org", "age" : 19, "dep" : "dev" }

При этом если поле не существовует, то mongodb создаст его:
> db.staffcoll.update({name:"Alex"},{$set:{lastname:"Petrovich"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Смотрим
> db.staffcoll.find({name:"Alex"},{_id:0})
{ "name" : "Alex", "email" : "alexxx@email.org", "age" : 19, "dep" : "dev", "lastname" : "Petrovich" }

Удаляем поле:
> db.staffcoll.update({name:"Alex"},{$unset:{lastname:"Petrovich"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.staffcoll.find({name:"Alex"},{_id:0})
{ "name" : "Alex", "email" : "alexxx@email.org", "age" : 19, "dep" : "dev" }

$inc

db.[COLLECTION].update({selector},{$inc:{[FIELD]:[VALUE]}}) — инкремент/декремент на указанное значение поля

Модифицируем следующий документ
> db.staffcoll.find({name:"Malex"},{_id:0})
{ "name" : "Malex", "email" : "malex@email.com", "age" : 25, "dep" : "dev" }
Сменим значение поля на 20
> db.staffcoll.update({name:"Malex"},{$inc:{age:20}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.staffcoll.find({name:"Malex"},{_id:0})
{ "name" : "Malex", "email" : "malex@email.com", "age" : 45, "dep" : "dev" }

Чтоб произвести декеремент, необходимо указать отрицательное число
> db.staffcoll.update({name:"Malex"},{$inc:{age:-10}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Смотрим
> db.staffcoll.find({name:"Malex"},{_id:0})
{ "name" : "Malex", "email" : "malex@email.com", "age" : 35, "dep" : "dev" }

$rename

db.[COLLECTION].update({selector},{$rename:{[FIELD]:[NEWFIELD]}}) — переименование поля

Переименуем поле name этого документа
> db.staffcoll.find({name:"Alex"},{_id:0})
{ "name" : "Alex", "email" : "alexxx@email.org", "age" : 19, "dep" : "dev" }
Переименовываем
> db.staffcoll.update({name:"Alex"},{$rename:{"name":"firstname"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.staffcoll.find({email:"alexxx@email.org"},{_id:0})
{ "email" : "alexxx@email.org", "age" : 19, "dep" : "dev", "firstname" : "Alex" }

Модификация нескольких документов — multi

Дополнительный флаг multi позволяет одновременно модифицировать несколько документов,
если выставить данный флаг в true. По умолчанию false, поэтому даже если под условия селектора попадут несколько документов, то обновится только один — первый найденный.

Модифицируем данные документы
> db.staffcoll.find({name:/lex/i})
{ "_id" : ObjectId("5b56acf6bf4ec3cb163bca36"), "email" : "alexxx@email.org", "age" : 19, "dep" : "dev", "name" : "Alex" }
{ "_id" : ObjectId("5b56acf6bf4ec3cb163bca37"), "name" : "Malex", "email" : "malex@email.com", "age" : 35, "dep" : "dev" }
Изменим значение поля dev
> db.staffcoll.update({name:/lex/i},{$set:{dep:"devOPS"}},{multi:true})
WriteResult({ "nMatched" : 2, "nUpserted" : 0, "nModified" : 2 })
Проверяем
> db.staffcoll.find({name:/lex/i})
{ "_id" : ObjectId("5b56acf6bf4ec3cb163bca36"), "email" : "alexxx@email.org", "age" : 19, "dep" : "devOPS", "name" : "Alex" }
{ "_id" : ObjectId("5b56acf6bf4ec3cb163bca37"), "name" : "Malex", "email" : "malex@email.com", "age" : 35, "dep" : "devOPS" }

Модификация массивов в документе

Для того чтоб именить отдельный эл-нт массива используется команда:
db.[COLLECTION].update(selector,{$set:{[FIELD.INDEX]:[VALUE]}}) — изменить значение поля в массиве по индексу

Модифицируем одно из значений данного массива
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Belta", "Ist" ] }
К примеру, поменяем 2й эл-нт массива
> db.cars.update({company:"Toyota"},{$set:{"models.1":"Crown"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Crown", "Ist" ] }

$push,$addToSet

db.[COLLECTION].update(selector,{$push:{[FIELD]:[VALUE]}}) добавить эл-нт в конец массива без проверки существования
db.[COLLECTION].update(selector,{$addToSet:{[FIELD]:[VALUE]}}) добавить эл-нт в конец массива с проверкой существования

Добавим эл-нт в конец массива
> db.cars.update({company:"Toyota"},{$push:{"models":"Belta"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Crown", "Ist", "Belta" ] }

Добваим еще один эл-нт, который уже есть в массиве
> db.cars.update({company:"Toyota"},{$push:{"models":"Crown"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Смотрим
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Crown", "Ist", "Belta", "Crown" ] }

Попробуем еще раз добавить один эл-нт в массив, но уже с проверкой существования
> db.cars.update({company:"Toyota"},{$addToSet:{"models":"Crown"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 0 })
Как видим, массив не изменился
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Crown", "Ist", "Belta", "Crown" ] }
$each

Если необходимо добавть сразу несколько эл-ов в массив, то используется модификатор $each, можно использовать для обоих операторов $addToSet и $push

Будем модифицировать данный документ
> db.cars.find({"company" : "Toyota"},{_id:0})
{"company" : "Toyota", "models" : [ "Celica", "Crown", "Ist", "Belta", "Crown"] }
Добавляем сразу несолкько эл-ов
> db.cars.update({"company":"Toyota"},{$push:{models:{$each:["Crown","Crown","Crown"]}}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.cars.find({"company" : "Toyota"},{_id:0})
{"company" : "Toyota", "models" : [ "Celica", "Crown", "Ist", "Belta", "Crown", "Crown", "Crown","Crown" ] }

$pull,$pullAll,$pop

db.[COLLECTION].update(selector,{$pull:{[FIELD]:[VALUE]}}) удалить определенный эл-нт из массива
db.[COLLECTION].update(selector,{$pullAll:{FIELD]:[VALUE1,VALUE2,VALUE3...]}}) удалить несколько эл-нов из массива
db.[COLLECTION].update(selector,{$pop:{[FIELD]:1/-1}}) удалить первый или последний эл-нт / value -1 или 1

Удяляем эл-ты массива с определенным значением
> db.cars.update({company:"Toyota"},{$pull:{"models":"Crown"}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Как видим удалились все эл-ты "Crown"
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Ist", "Belta" ] }

Удалим несколько эл-ов из массива данного документа
> db.cars.find({"company" : "Nissan"},{_id:0})
{ "company" : "Nissan", "models" : [ "Juke", "Note", "Teana", "Cube", "Safari" ] }
Удаляем
> db.cars.update({"company" : "Nissan"},{$pullAll:{"models" : ["Juke","Teana","Safari"]}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Проверяем
> db.cars.find({"company" : "Nissan"},{_id:0})
{ "company" : "Nissan", "models" : [ "Note", "Cube" ] }

Удалим последний э-нт массива
> db.cars.update({company:"Toyota"},{$pop:{"models":1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Смотрим
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Celica", "Ist" ] }
Удалим первый э-нт массива
> db.cars.update({company:"Toyota"},{$pop:{"models":-1}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
Смотрим
> db.cars.find({company:"Toyota"},{_id:0})
{ "company" : "Toyota", "models" : [ "Ist" ] }

Удаление документа

Документы в mongodb удаляются с помощью метода remove()
db.[COLLECTION].remove({selector}) — удалить документ

Удаляем
> db.assetscoll.find({"item" : "NoteBook"})
{ "_id" : ObjectId("5b515bd60dc6ea027cff0662"), "assetId" : 4, "item" : "NoteBook", "state" : "In Use", "ownerEmail" : "oleg@email.com", "loc" : "admin" }
Проверяем
> db.assetscoll.remove({"item" : "NoteBook"})
WriteResult({ "nRemoved" : 1 })

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *