Метод call

Метод call и apply достаточно древние - они оба из стандарта ES3. Суть создания и работы методов - заставить некоторую произвольную функцию работать на каком-то объекте. Точнее - использовать контекст этого объекта.

Чтобы было понятнее, начнем с примера. Есть функция, которая работает таким образом:

function getName() {
  const name = this.name
  console.log(name)
}

Что будет, если вызвать эту функцию таким образом?

getName()

Сложный вопрос, так как мы видим, что в теле функции используется ключевое слово this. Это - ссылка на текущий объект и на свойство name этого объекта. Что это за объект? Неизвестно. Все будет зависеть от того, где будет вызвана функция getName() на исполнение. Допустим, если вызвать функцию в консоли браузера, то парсер обратиться к глобальному объекту window и попробует найти у него свойство name. В итоге мы получим undefined, так как вряд ли у объекта window есть свойство name.

При помощи метода call можно “привязать” функцию getName() к любому объекту. Другими словами - привязать контекст функции getName() к контексту объекта. Как?

Допустим, у нас есть объект:

const user1 = {
  name: 'Ivan',
  position: 'frontent developer',
  salary: 1200
}

Мы сделаем так:

const result1 = getName.call(user1)

Что будет происходить здесь? В этом случае ключевое слово this (в теле функции getName) будет указывать на объект user1, у которого есть свойство name. Как результат - в константе result1 будет находиться значение Ivan.

Если создадим еще один объект:

const user2 = {
  name: 'Joshua',
  position: 'ui designer',
  salary: 2200
}

И на нем вызовем функцию getName():

const result2 = getName.call(user2)

Что будет? В этом случае функция getName будет ссылаться уже на объект user2! И в константе result2 уже будет значение свойства name объекта user2 - Joshua.

call - более сложный вариант

Рассмотрим более сложный случай - когда функция принимает аргумент(ы). Допустим, такая функция,

function promote(position, salary) {
  this.salary = salary
  this.position = position
  return this.position + ' earns ' + this.salary + ' dollars'
}

И есть два объекта:

const junior = {
  name: 'Fritz',
  position: 'junior developer',
  salary: 1000
}
const middle = {
  name: 'Max',
  position: 'middle developer',
  salary: 2000
}
const senior = {
  name: 'Manu',
  position: 'senior developer',
  salary: 3000
}

Вызовем функцию promote() на каждом из объектов:

const result1 = promote.call(junior, 'super junior developer', 1200)
const result2 = promote.call(middle, 'super middle developer', 2200)
const result3 = promote.call(senior, 'super senior developer', 3200)

Что здесь произойдет? При каждом вызове функции promote() у нее будет разный контекст выполнения - объект junior, middle или senior. И обращаться функция promote() будет каждый раз к свойствам разных объектов - junior, middle или senior. Соответственно, результат тоже будет разным:

super junior developer earns 1200 dollars
super middle developer earns 2200 dollars
super senior developer earns 3200 dollars

Метод apply

Метод apply очень похож на метод call, за одним исключением. Аргументы метод apply принимает в виде массива, а не в виде списка, как метод call.

Проиллюстрируем пример - переделаем вызов функции promote() при помощи метода apply:

const resultA = promote.apply(junior, [ 'super junior developer', 1200 ])
const resultB = promote.apply(middle, [ 'super middle developer', 2200 ])
const resultC = promote.apply(senior, [ 'super senior developer', 3200 ])

Видим, что аргументы передаются в виде массива, но результат будет тот же. Как часто упоминается в различных туториалах, это сделано для того, чтобы передать неограниченное и заранее неизвестное количество аргументов.

Метод bind

Этот метод похож на предыдущие два - call и apply. Однако, у него есть два отличия - этот метод появился в стандарте ES5; и второе отличие - этот метод позволяет выполнить отложенный вызов функции.

То есть - метод call или apply вызываются на исполнение сразу, и результат их работы мы получаем сразу. С методом bind немного иначе:

const resultAA = promote.bind(junior)
const resultBB = promote.bind(middle)
const resultCC = promote.bind(senior)

Что мы сдесь сделали? Мы вызвали функции promote() и передали ей контекст выполнения; результат - экземпляр функции promote() с уже встроенным контекстом выполнения; экземпляр помещен в константу resultAA, resultBB или resultCC. Другими словами - это готовые функции с контекстом.

Осталось вызвать любую из них и передать ей аргументы, которые она ожидает:

const resultAAA = resultAA('super junior developer', 1200)
const resultBBB = resultBB('super middle developer', 2200)
const resultCCC = resultCC('super senior developer', 3200)

Получим результат:

super junior developer earns 1200 dollars
super middle developer earns 2200 dollars
super senior developer earns 3200 dollars

Видим - мы получили отложенный вызов каждой из функций.

MongoDB

Приступили к самому основному - операциям создания, чтения, изменения и удаления документов в MongoDB.

Аббревиатура для этих четырех операций - CRUD ( Create, Read, Update, Delete ).

В этом обзоре будет рассмотрен процесс создания документа - Create.

Два основных метода для создания нового документа в коллекции - метод insert и метод save.

Метод insert()

Команда создания нового документа в коллекции выглядит так:

db.COLLECTION_NAME.insert(document)

COLLECTION_NAME - это имя коллекции, в которой будет создаваться новый документ. document - это JavaScript-объект.

Создам новый документ в коллекции customers базы данных users. Для этого перейду в эту базу данных:

> use users
switched to db users

Создам коллецию customers в базе данных users:

> db.createCollection('customers')
{ "ok" : 1 }

Создам в коллекции customers новый документ. Можно использовать как одинарные, так и двойные кавычки - дело вкуса:

> db.customers.insert( { name: 'Leanne Graham', username: 'Bret', email: 'sincere@april.biz' } )
WriteResult({ "nInserted" : 1 })

MongoDB выдает отчет о выполнении команды в строке:

...
WriteResult({ "nInserted" : 1 })

Видно, что операция WriteResult успешно выполнилась - nInserted в значении true.

Как хорошо видно, создаваемый документ - это объект. Если нужно создать сразу несколько документов, то методу insert передается массив этих объектов:

> db.customers.insert( [ { name: 'Ervin Howell', username: 'Antonette', email: 'shanna@melissa.tv' }, { name: 'Clementine Bauch', username: 'Samantha', email: 'nathan@yesenia.net' } ] )
BulkWriteResult({
	"writeErrors" : [ ],
	"writeConcernErrors" : [ ],
	"nInserted" : 2,
	"nUpserted" : 0,
	"nMatched" : 0,
	"nModified" : 0,
	"nRemoved" : 0,
	"upserted" : [ ]
})

BulkWriteResult выдает подробную информацию о выполненных операциях. Видно, что была выполнена только операция создания документа - “nInserted” : 2.

Просмотр списка документов

Вывести список созданных документов в коллекции customers можно при помощи метода .find():

> db.customers.find()
{ "_id" : ObjectId("59200cdc2bd83e7289a5cae4"), "name" : "Leanne Graham", "username" : "Bret", "email" : "sincere@april.biz" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae5"), "name" : "Ervin Howell", "username" : "Antonette", "email" : "shanna@melissa.tv" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae6"), "name" : "Clementine Bauch", "username" : "Samantha", "email" : "nathan@yesenia.net" }
>

Видно, что у каждого созданного мною документа есть ключ _id со значением ObjectId(). Этого ключа я не указывал при создании документа.

Все правильно - этот ключ и его значение MongoDB генерирует автоматически и присваивает каждому создаваемому документу. Таким образом MongoDB делает все документы уникальными - нет ни одного документа с одинаковым _id.

Можно сделать вывод метода .find() более читабельным, если подключить к нему по цепочке еще один метод - .pretty():

> db.customers.find().pretty()
{
	"_id" : ObjectId("59200cdc2bd83e7289a5cae4"),
	"name" : "Leanne Graham",
	"username" : "Bret",
	"email" : "sincere@april.biz"
}
{
	"_id" : ObjectId("59200e3b2bd83e7289a5cae5"),
	"name" : "Ervin Howell",
	"username" : "Antonette",
	"email" : "shanna@melissa.tv"
}
{
	"_id" : ObjectId("59200e3b2bd83e7289a5cae6"),
	"name" : "Clementine Bauch",
	"username" : "Samantha",
	"email" : "nathan@yesenia.net"
}
>

Метод save()

С помощью метода save() также можно создавать новый документ в коллекции. Создам еще один документ:

> db.customers.save( { name: 'Patricia Lebsack', username: 'Karianne', email: 'julianne.conner@kory.org' } )
WriteResult({ "nInserted" : 1 })

Сообщение от MongoDB говорит мне, что операция была выполнена успешно. Посмотрю на результат:

> db.customers.find()
{ "_id" : ObjectId("59200cdc2bd83e7289a5cae4"), "name" : "Leanne Graham", "username" : "Bret", "email" : "sincere@april.biz" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae5"), "name" : "Ervin Howell", "username" : "Antonette", "email" : "shanna@melissa.tv" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae6"), "name" : "Clementine Bauch", "username" : "Samantha", "email" : "nathan@yesenia.net" }
{ "_id" : ObjectId("592013152bd83e7289a5cae7"), "name" : "Patricia Lebsack", "username" : "Karianne", "email" : "julianne.conner@kory.org" }
>

Отличие метода save() от метода insert() заключается в том, что если при создании документа будет передан ключ _id уже существующего документа, то существующий документ будет перезаписан новым.

Вот у меня создан документ:

> db.customers.save( { name: 'Chelsey Dietrich', username: 'kamren', email: 'Lucio_Hettinger@annie.ca' } )
WriteResult({ "nInserted" : 1 })

И он успешно добавлен в коллекцию customers с уникальным ключом “_id” : ObjectId(“5920166b986c86064996f59e”):

> db.customers.find()
{ "_id" : ObjectId("59200cdc2bd83e7289a5cae4"), "name" : "Leanne Graham", "username" : "Bret", "email" : "sincere@april.biz" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae5"), "name" : "Ervin Howell", "username" : "Antonette", "email" : "shanna@melissa.tv" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae6"), "name" : "Clementine Bauch", "username" : "Samantha", "email" : "nathan@yesenia.net" }
{ "_id" : ObjectId("5920166b986c86064996f59e"), "name" : "Chelsey Dietrich", "username" : "kamren", "email" : "Lucio_Hettinger@annie.ca" }
> 

Теперь я создаю новый документ, но передаю в него существующую пару ключ-значение “_id” : ObjectId(“5920166b986c86064996f59e”):

> db.customers.save( { "_id" : ObjectId("5920166b986c86064996f59e"), name: 'Chelsey Dietrich', username: 'chelsey', email: 'c.dietrich@gmail.com' } )
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })

Смотрю результат:

> db.customers.find()
{ "_id" : ObjectId("59200cdc2bd83e7289a5cae4"), "name" : "Leanne Graham", "username" : "Bret", "email" : "sincere@april.biz" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae5"), "name" : "Ervin Howell", "username" : "Antonette", "email" : "shanna@melissa.tv" }
{ "_id" : ObjectId("59200e3b2bd83e7289a5cae6"), "name" : "Clementine Bauch", "username" : "Samantha", "email" : "nathan@yesenia.net" }
{ "_id" : ObjectId("5920166b986c86064996f59e"), "name" : "Chelsey Dietrich", "username" : "chelsey", "email" : "c.dietrich@gmail.com" }
>

… и вижу, что последний документ был полностью перезаписан. Вуаля.

На этом все.


MongoDB

Что такое document

Понятие документа - основа MongoDB. Недаром говорится, что MongoDB - документо-ориентированная система управления базами данных.

Document входит в состав collection и наполняет ее содержимым. Document - это обычный JSON-объект.

Если есть навык создания и работы с JSON-объектами, то уже можно создавать документы в MongoDB.

Простой пример документа в базе данных MongoDB:

{
  "_id" : ObjectId("591f49970f7b726a5beb58af"),
  "name" : "Anna"
}

Стоит обратить внимание на ключ “_id” - этот ключ и значение ключа MongoDB автоматически генерирует для уникальной идентификации каждого документа в базе данных.

Чуть более сложный пример документа в MongoDB:

{
	"_id" : ObjectId("591f49970f7b726a5beb58af"),
	"name" : "Anna",
	"surname" : "Tudor",
	"music" : [
		"country",
		"blues",
		"chill-out"
	],
	"age" : 18,
	"virgin" : true
}

В данном случае документ состоит из нескольких типов данных - Number, Array, String, Boolean.

Два документа в коллекции canada базы данных users:

{
	"_id" : ObjectId("591f49970f7b726a5beb58af"),
	"name" : "Anna",
	"surname" : "Tudor",
	"music" : [
		"country",
		"blues",
		"chill-out"
	],
	"age" : 18,
	"virgin" : true
}
{
	"_id" : ObjectId("591f4eaf02ed4d6e1d81bc97"),
	"name" : "Leanne Graham",
	"username" : "Bret",
	"email" : "Sincere@april.biz",
	"address" : {
		"street" : "Kulas Light",
		"suite" : "Apt. 556",
		"city" : "Gwenborough",
		"zipcode" : "92998-3874",
		"geo" : {
			"lat" : "-37.3159",
			"lng" : "81.1496"
		}
	},
	"phone" : "1-770-736-8031 x56442",
	"website" : "hildegard.org"
}

Таких документов в коллекции canada может быть сколько угодно.

Вот в принципе и все, что нужно знать о документах в MongoDB.

На этом все.


MongoDB

Что такое collection

В базах данных MongoDB данные объединяются в коллекции - collection. В одной базе данных может быть от одной до многих collections.

Смысл collection - объединять однотипные данные. То есть данные, котороые можно объединить по какому-либо признаку.

Например, в базе данных animals может быть две collections - cats и dogs. В коллекции cats хранятся все данные, о которых можно сказать - “это данные по кошкам”. В коллекции dogs хранятся “все данные по собакам”.

Создание collection

В базе данных создать collection можно командой:

db.createCollection('NAME_COLLECTION')

Например, я создам две коллекции cats и dogs в базе данных animals. Для этого создам базу данных animals:

> use animals
switched to db animals
>

Создам коллекцию cats:

> db.createCollection('cats')
{ "ok" : 1 }

Создам коллекцию dogs:

> db.createCollection('dogs')
{ "ok" : 1 }

Посмотреть список существующих колекций базы данных можно командой:

show collections

Проверю, создались ли успешно коллеции cats и dogs в базе данных animals:

> show collections
cats
dogs

Переименование collection

Операция переименования collection в MongoDB выполняется командой:

db.collection.renameCollection('NEW_NAME')

Например, я создал коллекцию bird в базе данных animals:

> db.createCollection('bird')
{ "ok" : 1 }
> show collections
bird
cats
dogs
>

… и хочу переименовать эту коллецию в birds:

> db.bird.renameCollection('birds')
{ "ok" : 1 }
> show collections
birds
cats
dogs
>

В результате коллекция bird успешно переименована в birds.

Удаление collection

В MongoDB удаление коллекции выполняется командой:

db.COLLECTION_NAME.drop()

Например, я хочу удалить коллекцию birds из базы данных animals:

> db.birds.drop()
true
> show collections
cats
dogs
>

Коллекция birds успешно удалена из базы данных.

Создание collection - автоматический способ

В MongoDB имеется способ автоматического создания collection - путем добавления документа в новую коллецию при помощи метода insert.

Например, коллекции insects в базе данных animals не существует. В будущую коллекцию insects я добавлю документ cockroach и тем самым автоматически создам коллецию insects:

> db.insects.insert({ name: 'cockroach' })
WriteResult({ "nInserted" : 1 })
> show collections
cats
dogs
insects
>

На этом все.


MongoDB

Создание базы данных

В двух предыдущих примерах научились устанавливать MongoDB. А также научились запускать и останавливать сервер MongoDB.

Настало время научиться создавать базы данных в MongoDB. Для этого нужно запустить и зайти в командную оболочку MongoDB.

Командная оболочка MongoDB носит имя mongo-shell и запускается в Linux одной командой:

mongo

В консоли отобразится сообщение и приглашение командной строки, говорящее о том, что мы находимся в командной оболочке MongoDB:

MongoDB shell version v3.4.4
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.4
...
> 

Список баз данных

Увидеть список всех существующих баз данных можно командой:

show dbs

Вот список баз данных на момент установки MongoDB в системе Linux. Видно, что обе базы пустые:

> show dbs
admin  0.000GB
local  0.000GB
> 

Создать базу данных

Команда создания новой базы данных в MongoDB очень проста:

use DATABASE_NAME

Например, создам новую базу данных по имени users:

> use users
switched to db users
> 

Команда user универсальная. Если база данных users уже существует, то будет выполнен просто переход в эту базу данных.

Если базы данных users не существует, то она будет создана и будет выполнен автоматический переход в эту базу данных.

Имя базы данных

Узнать имя текущей ( в которой на данный момент нахожусь ) базы данных можно командой:

db

В моем случае это будет так:

> db
users
>

Удаление базы данных

Удалить базу данных можно командой:

db.dropDatabase()

Важный момент - нужно находиться в той базе данных, которую необходимо удалить. Команда dropDatabase() не принимает аргументов.

Например, я хочу удалить базу данных users:

> show dbs
admin  0.000GB
local  0.000GB
users  0.000GB
>

Для этого я перейду в базу данных users:

> use users
switched to db users
>

И выполню команду dropDatabase():

> db.dropDatabase()
{ "dropped" : "users", "ok" : 1 }
>

Посмотрю список баз данных после удаления базы users и удостоверюсь, что она удалена успешно:

> show dbs
admin  0.000GB
local  0.000GB
>

На этом все.