MongoDB Подробное руководство

MongoDB состоит из: БД, которые состоят из коллекций. Коллекции, в свою очередь, состоят из документов. Каждый документ состоит из полейwww.mongodb.com

Обновленная статья

MongoDB клиенты

Конфиг

В папке bin создайте файл и назовите его mongodb.config.

Указываем в этом файле путь, где будем хранить БД, например, для windows: dbpath=c:\mongodb\data

Запуск

  • mongod — это сервер
  • mongo — клиентская консоль

Стартуем mongod (сервер):

mongod --config c:\mongodb\bin\mongodb.config
// не забудьте заранее создать папку data

Команда mongo позволяет подключиться к запущенному серверу (стартуем mongo оболочку/shell).

mongo

Работа с БД

Выводим все БД в mongo:

show dbs

Переходим (и одновременно создаем) к нужной БД

use name_bd

Команды db возвращает имя БД, внутри которой мы сейчас находимся:

db
//test

Коллекции

Показать все коллекции в БД

show collections

    Метод find()

Показать весь контент нужной коллекции

db.collection_name.find()

Пример:

db.band.find()
db.band.find().pretty()

Метод pretty выводит результат в удобном для чтения виде.

    Метод count()

Метод count выводит количество документов в коллекции:

db.band.count()

    Метод remove()

Метод remove используется, чтобы удалить документ из коллекции (или всю коллекцию).

db.unicorns.remove({name: "Leto"})

    Метод insert()

Заносим данные в коллекцию band (и, видимо, создаем тем самым коллекцию band, если ее нет):

db.band.insert({name: 'Queen', bid: '3'})

Добавим составы в коллекцию band:

db.band.update({bid: '1'}, {$set: {members: [{name: "Jimmy Page", id: "1"}, {name: "robert Plant", id: "2"}, {name: "John Bonham", id: "3"}, {name: "John Paul Jones", id: "4"}]}})

db.band.update({bid: '2'}, {$set: {members: [{name: "Syd Barret", id: "5"}, {name: "Roger Waters", id: "6"}, {name: "Nick Mason", id: "7"}, {name: "Richard Wright", id: "8"}, {name: "David Gilmour", id: "9"}]}})

Мы можем добавлять данные, не декларируя их предварительно: свойство members. Отсутствует схема: легко добавили массив объектов.


Модификация данных

    Оператор $set

Оператор $set заставляет команду update модифицировать лишь те ключи, которые ему переданы (см. пример выше).

    Оператор $unset

Оператор $unset удаляет указанный ключ

db.collection.update({id: 2}, {$unset: {myKey: 1}});
db.example.update({}, {$unset: {words:1}}, false, true);

    Оператор $inc

Оператор $inc увеличивает значение поля на указанную величину

db.collection.update({id: 2}, {$inc: {myCounter: 111}});
db.collection.update( {"players.playerName":"Joe"}, { $inc : { "players.$.playerScore" : 1 } }

    Оператор $rename

Оператор $rename позволяет переименовать поля

db.collection.update({id: 2}, {$rename: {"old_name": "new_name"}});
db.band.update({bid: "1"},{$rename:{"members":"members_new"}});

Индексы

metanit.com/nosql/mongodb proselyte.net/tutorials/mongodb/indexing

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

Индексы – это специальные структуры данных, которые хранят небольшие части данных в форме, которая легко распознаётся. Они хранят значение определённого поля или набора полей, упорядоченных по значению поля, указанному в индексе.

Построим индекс по ключу bid:

db.band.ensureIndex({bid: 1})

ensureIndex устарел, начиная с версии 3.0, в данный момент является псевдонимом для db.collection.createIndex().

Схемы и модели

Схемы определяют структуру документов внутри коллекции, а модели используются для создания копий данных, хранящихся в документах.

I Основы

  • 1. Внутри MongoDB может быть ноль или более баз данных.
  • 2. База данных может иметь ноль или более «коллекций». (коллекция практически тоже что и таблица)
  • 3. Коллекции состоят из нуля или более «документов». Опять же, документ можно рассматривать как «строку».
  • 4. Документ состоит из одного или более «полей», которые — как можно догадаться — подобны «колонкам».
  • 5. «Индексы» в MongoDB почти идентичны таковым в реляционных базах данных.
  • 6. Важно понимать, что когда мы запрашиваем у MongoDB какие-либо данные, то она возвращает курсор, с которыми мы можем делать все что угодно.

Но есть отличия:

Основное различие в том, что реляционные базы данных определяют «колонки» на уровне «таблицы», в то время как документ-ориентированные базы данных определяют «поля» (в реляционных «колонки») на уровне «документа» (в релационных «запись»).

В конечном счёте дело в том, что коллекция не содержит информации о структуре содержащихся в ней данных. Информацию о полях содержит каждый отдельный документ.

    Метод insert

Мы не обязаны создавать коллекции явно. Мы просто можем вставить документ в новую коллекцию. Чтобы это сделать, используйте команду insert, передав ей вставляемый документ:

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

Селекторы запросов

Селектор запросов MongoDB (это JSON-объект) аналогичен предложению where SQL-запроса. Как таковой он используется для поиска, подсчёта, обновления и удаления документов из коллекций.

Селектор — это JSON-объект, в простейшем случае это может быть даже {}, что означает выборку всех документов (аналогичным образом работает null). Если нам нужно выбрать всех единорогов (англ. «unicorns») женского рода, можно воспользоваться селектором {gender:'f'}.

{поле: значение} используется для поиска всех документов, у которых есть ‘поле’ и у него есть ‘значение’.

{поле1: значение1, поле2: значение2} работает как логическое И.

    Оператор $lt, $lte, $gt, $gte, $ne

Специальные операторы $lt$lte$gt$gte и $ne используются для выражения операций «меньше», «меньше или равно», «больше», «больше или равно», и «не равно».

Пример использовани селекторов с командой find (но также селекторы могут быть использованы с removecountupdate):

Например, чтобы получить всех самцов единорога, весящих более 700 фунтов, мы можем написать:

db.unicorns.find({gender: 'm', weight: {$gt: 700}})

    Оператор $exists

Оператор $exists используется для проверки наличия или отсутствия поля, например:

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

    Оператор $or

Оператор $or используется как ИЛИ

db.unicorns.find({gender: 'f', $or: [{loves: 'apple'}, {loves: 'orange'}, {weight: {$lt: 500}}]})
//... или любят яблоки, или любят апельсины, или весят менее 500 фунтов

Отметьте

db.unicorns.insert({name: 'Leia', dob: new Date(2001, 9, 8, 14, 53), loves: ['apple', 'watermelon'], weight: 601, gender: 'f', vampires: 33});

Поле loves это массив. MongoDB поддерживает массивы как объекты первого класса. Самое интересное это та простота, с которой делается выборка по значению массива: {loves: ‘watermelon’} вернёт нам все документы, у которых watermelon является одним из значений поля loves.

    Оператор $where

Оператор $where (в след. разделах)

Самый гибкий оператор — $where, позволяющий нам передавать JavaScript для его выполнения на сервере.

    Оператор ObjectId

ObjectId, сгенерированный MongoDB для поля _id, подставляется в селектор следующим образом:

db.unicorns.find({_id: ObjectId("TheObjectId")})

II update

В простейшей форме, update принимает 2 аргумента: селектор для выборки и то, чем обновить соответствующее поле. Второй параметр используется для полной замены оригинала:

db.unicorns.update({name: 'Roooooodles'}, {weight: 590})

По умолчанию, update обновляет лишь первый найденный документ

    Модификатор $set

Модификатор $set обновляет конкретные поля, а не весь документ.

Если вам нужно всего лишь изменить пару полей, лучше всего использовать модификатор $set:

db.unicorns.update({weight: 590}, {$set: {name: 'Roooooodles', dob: new Date(1979, 7, 18, 18, 44), loves: ['apple'], gender: 'm', vampires: 99}})
db.unicorns.update({name: 'Roooooodles'}, {$set: {weight: 590}})

Другие модификаторы, которые действуют непосредственно на поля, а не на весь документ:

    модификатор $inc

модификатор $inc — увеличить или уменьшить значение поля.

db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}})

модификатор $push — позволяет добавить данные в массив

db.unicorns.update({name: 'Aurora'}, {$push: {loves: 'sugar'}})

Обновление/вставка (при отсутствии элемента)

Не забывайте использовать модификатор $set, если вам нужно обновить лишь некоторые поля.

    Разрешаем вставку при обновлении (3-й параметр)

Чтобы разрешить вставку при обновлении (если элемент не будет найден), установите третий параметр в true.

db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}});
db.hits.find();

Вставки и обновления не будет, так как 3-й параметр опущен, а документа с {page: 'unicorns'} отсутствует в коллекции.

db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
db.hits.find();

Поскольку документы с полем page, равным unicorns, не существуют, то будет создан новый документ. Если выполнить это вторично, существующий документ будет обновлён, и поле hits увеличится до 2.

Одновременно создастся коллекция hits, если она отсутствует.

    Множественные обновления (4-й параметр)

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

db.unicorns.update({}, {$set: {vaccinated: true }}, false, true);

Этим мы обновили все поля добавив везде поле vaccinated со значением true

III Команда find (курсор)

Курсор базы данных — это объект БД, который позволяет приложениям работать с записями «по-одной», а не с множеством сразу. То есть курсор (как мы помним это объект), который позволяет передвигаться по выборке (назад на одно, вперед на одну, в конец/начало) при помощи своих методов.

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

db.unicorns.find(null, {name: 1});
cursor = db.unicorns.find(null, {name: 1});

_id по умолчанию возвращается всегда. Но мы можем исключить _id следующим образом: {name:1, _id: 0}.

Получаем все поля, кроме поля name:

db.unicorns.find({}, {name: 0})

Как уже упоминалось, результатом find является курсор. Поэтому мы можем присоединить к нему ряд методов:

    Сортировка (метод sort)

Синтаксис метода sort: мы указываем поля, по которым надо сортировать, используя 1 для сортировки по возрастанию и -1 для сортировки по убыванию. Например:

db.unicorns.find().sort({weight: -1})
// по убыванию 999,998,997 ...
db.unicorns.find({}, {name: true}).sort({name: -1})

Но для сортировки большого объема данных в Mongo необходимо использовать индексы.


    Метод limit()

db.unicorns.find({}, {name: true}).sort({name: -1}).limit(3)

    Метод skip()

Метод skip() позволяет пропустить определенное количество записей.

db.unicorns.find({}, {name: true}).sort({name: -1}).limit(3).skip(1)

Обратите внимание как мы соединяем методы в цепочки.

Моделирование данных

MongoDB не поддерживает JOIN. По существу мы должны делать второй запрос, чтобы найти связанные данные.

p.s: Для создания нового ObjectID используется следующий код: NewObjectId = ObjectId()

Когда требуется смоделировать отношения «один-ко-многим» или «многие-ко-многим» можно использовать массивы ( в MongoDB массивы это объекты первого класса).

db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Siona', manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")] })

При этом данный find сработает:

db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730")})

Массивы значений намного удобнее в использовании, нежели таблицы связи «многие-ко-многим»

    Вложенные документы

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

db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d734"), name: 'Ghanima', family: {mother: 'Chani', father: 'Paul', brother: ObjectId("4d85c7039ab0fd70a117d730")}})

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

db.employees.find({'family.mother': 'Chani'})

    Денормализация

Традиционный путь ассоциировать пользователя с его постом — это колонка userid в таблице posts. С такой моделью нельзя отобразить список постов без дополнительного извлечения данных (JOIN) из таблицы пользователей. Возможное решение — хранить имя пользователя (name) вместе с userid для каждого поста.


Команды (выжимка)

db.version()
//показывает номер версии сервера
db.getCollectionNames()
//получить список коллекций внутри нашей БД
db.unicorns.find()
//вернет список документов (записей)
db.unicorns.remove()
//поскольку мы не передали селектора, произойдёт удаление всех документов
//Например, чтобы получить всех самцов единорога, весящих более 700 фунтов, мы можем написать:
db.unicorns.find({gender: 'm', weight: {$gt: 700}})
//Оператор $exists используется для проверки наличия или отсутствия поля, например:
db.unicorns.find({vampires: {$exists: false}})
//Оператор $or используется как ИЛИ
db.unicorns.find({gender: 'f', $or: [{loves: 'apple'}, {loves: 'orange'}, {weight: {$lt: 500}}]})
//update принимает 2 аргумента: селектор (where) для выборки и то, чем обновить соответствующее поле.
//Второй параметр используется для полной замены оригинала
db.unicorns.update({name: 'Roooooodles'}, {weight: 590})
//Модификатор $set обновляет конкретные поля, а не весь документ
db.unicorns.update({name: 'Roooooodles'}, {$set: {weight: 590}})
//модификатор $inc - увеличить или уменьшить значение поля
db.unicorns.update({name: 'Pilot'}, {$inc: {vampires: -2}})
//модификатор $push - позволяет добавить данные в массив
db.unicorns.update({name: 'Aurora'}, {$push: {loves: 'sugar'}})
//Обновление/вставка обновляет документ, если он найден, или создаёт новый — если не найден.
//Чтобы разрешить вставку при обновлении, установите третий параметр в true (ниже мы создаем коллекцию hits, если ее нет)
db.hits.update({page: 'unicorns'}, {$inc: {hits: 1}}, true);
//если установить 4-й параметр в true, то обновятся все документы
db.unicorns.update({}, {$set: {vaccinated: true }}, false, true);
//Второй необязательный параметр у find указывает на список полей, которые мы хотим получить.
db.unicorns.find(null, { name:true })
//получаем все поля, кроме поля name:
db.unicorns.find({}, {name: 0})
//сортировка по убыванию
db.unicorns.find().sort({weight: -1})
// сортируем по весу, но получаем 2 и 3 по весу единорога, пропуская 1-го
db.unicorns.find().sort({weight: -1}).limit(2).skip(1)
//подсчитать кол-во единорогов на счету которых более 60 вампиров
db.unicorns.count({vampires: {$gt: 50}})
//Когда требуется смоделировать отношения «один-ко-многим» или «многие-ко-многим» можно использовать массивы
db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d733"), name: 'Siona', manager: [ObjectId("4d85c7039ab0fd70a117d730"), ObjectId("4d85c7039ab0fd70a117d732")] })
// Ищем значение в массиве manager
db.employees.find({manager: ObjectId("4d85c7039ab0fd70a117d730")})
//MongoDB поддерживает вложенные документы:
db.employees.insert({_id: ObjectId("4d85c7039ab0fd70a117d734"), name: 'Ghanima', family: {mother: 'Chani', father: 'Paul', brother: ObjectId("4d85c7039ab0fd70a117d730")}})
//Вложенные документы можно запрашивать с помощью точечной нотации:
db.employees.find({'family.mother': 'Chani'})
// версия > 3.2
db.employees.updateOne(…);
db.employees.updateMany (…);

operator update (документация)


Подключение mongoDB в nodejs

// Retrieve
var MongoClient = require('mongodb').MongoClient;

// Connect to the db
MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
  if(!err) {
    console.log("We are connected");
  }
});

соединение с БД mongo DB

Mongoose

ODM – Object-Document Mapper (объектно-документное отображение). У mongo нет жесткой структуры, а вот Mongoose позволяет нам ввести понятие схемы.

    Установка и подключение

//install
$ npm install mongoose
//use
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function() {
    // connect
});

    Схема

Схема в Mongoose определяет метаданные модели — ее свойства, типы данных и ряд другой информации.

mongoosejs.com/docs/guide.html

var mongoose = require('mongoose');
var Schema = mongoose.Schema;


// внутри перечисляем наши поля
var blogSchema = new Schema({
    title:  String,
    author: String,
    body:   String,
    comments: [{ body: String, date: Date }],
    date: {
        type: Date,
        default: Date.now,
        required: [true, 'Укажите дату']
    },
    hidden: Boolean,
    meta: {
        votes: Number,
        favs:  Number
    }
});


var Blog = mongoose.model('Blog', blogSchema);
// ready to go!

    Типы схем

mongoosejs.com/docs/schematypes.html


    Модель

http://mongoosejs.com/docs/models.html Модели — это конструкторы, составленные из определения нашей схемы. Экземпляры модели представляют собой документы, которые могут быть сохранены и извлечены из нашей БД.

var schema = new mongoose.Schema({ name: 'string', size: 'string' });
var Tank = mongoose.model('Tank', schema);

Первый параметр в методе mongoose.model указывает на название модели, а второй параметр — собственно схема.

    Поиск

http://mongoosejs.com/docs/queries.html

var Person = mongoose.model('Person', yourSchema);

//  { 'name.last': 'Ghost' }       - условие
//  'name occupation'              - выбираем нужные поля
//  function (err, person) { ...   - обрабатываем данные в callback'е

// find each person with a last name matching 'Ghost', selecting the `name` and `occupation` fields
Person.findOne({ 'name.last': 'Ghost' }, 'name occupation', function (err, person) {
  if (err) return handleError(err);
  console.log('%s %s is a %s.', person.name.first, person.name.last, person.occupation)
  // Space Ghost is a talk show host.
})

// находим все
Person.find({ 'name.last': 'Ghost' }, 'name occupation', function (err, docs) {})
// альтернатива callback
Person.find({ 'name.last': 'Ghost' }, 'name occupation').exec(function (err, docs) {})

    Сохраняем объект в БД

var Person = mongoose.model('Person', yourSchema);

var subject = new Person({name: 'John'});

subject.save(function(err) {
    if (err) return handkeError(err);
})

//или

Person.create({name: 'John'}, function(err, subject) {
    if (err) return handkeError(err);
})

    Редактирование и удаление



// меняем Karl на Johny
var query = {name: 'Karl'};

Model.update(query, {name: 'Johny'}, options, callback); // все заменит на  {name: 'Johny'}

Model.update(query, {$set: {name: 'Johny'}}, options, callback); // меняем только поле name

Person.findOne({name: 'Johny'}, function (err, person) {
    if (err) return handleError(err);
    person.name = 'Johny';
    person.save();
})

//удаление:
Model.remove({name: 'Johny'}, function (err, person) {
    if (err) return handleError(err);
})

С mongo можно использовать Promise от node.

mlab.com

mlab.com — это облачный сервис по предоставлению БД mongoDB.

  • Создаем БД
  • Добавляем пользователя
  • И подключаемся в своем приложении:
mongoose
    .connect(`mongodb://user_name:pass@ds147072.mlab.com:47072/name_bd`);

CRUD

CRUD — (create, read, update, delete — «создание, чтение,обновление, удаление») — 4 основные функции, используемые при работе базами данных.p.s.

node, а значит и mongo, применяется для высоконагруженных проектов, там, где необходимо передавать много информации, чаты, игры.

Обновленная статья

One thought on “MongoDB Подробное руководство

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

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