Работа с MongoDB: Структура БД и основы языка запросов

декабря 25, 2011  |  Published in MongoDB, Базы данных  |  4 Comments

mongoDBРаботая с MongoDB у нас имеется базовый объект — db, который представляет собой саму базу данных, точнее является ссылкой на одну из имеющихся баз данных (по умолчанию, запуская консоль это база данных с именем test). Далелее идут коллекции документов, использую dot-нотацию получаем доступ к коллекции следующим образом:

> db.collection_name

Коллекции представляют собой наборы документов или вложенных коллекций. Обратиться к документу можно используя различные запросы.

Для дальнейшего ознакомления с работой с MongoDB давайте запустим mongod и консоль mongo и создадим коллекцию.

db
//test

db.posts
//test.posts

for(x = 1;x <= 10; x ++ ){
  post = {"title":"Title for post # " + x,
  "content":"Content for post # " + x }
  db.posts.insert(post);
}

db.post.insert(post);

b.posts.findOne();
/*{
"_id" : ObjectId("4ef64c526e06ee4cec3dab4e"),
"title" : "Title for post # 1",
"content" : "Content for post # 1"
}*/

db.posts.find({title:"Title for post # 10"});
//{ "_id" : ObjectId("4ef64c526e06ee4cec3dab57"), "title" : "Title for post # 10", "content" : "Content for post # 10" }

Не сложно догадаться, что в цикле мы создаем уникальные документы и затем используя метод .insert() записываем их в коллекцию posts. Метод .findOne() используется для поиска одного единственного документа, если условие поиска не передано, то возвращается первый документ, а если условию соответствует несколько документов, то мы получаем только первый из них. Метод .find() используется для поиска всех документов, что соответствуют условию поиска. Если условие поиска не задано, то .find() возвратит все документы, что содержатся в коллекции.

Интересным моментов в работе с MongoDB являются индексы документов. Видите ли, инденксы в MongoDB не похожи на индексы в резяционных базах данных, точнее в большинстве случаев не похожи. В реляционных БД мы используем чаще всего целочисленные индексы в десятичной системе, которые ничего не означают, кроме того, какая запись за какой идет, чем запись новее — тем больше ее индекс. В MongoDB индексы несут значительно большую информацию о документе, чем иденксы в реляционных БД о записях. Стандартный ID в MongoDB является объектом особого типа — ObjectId и представляет из себя 12-байтное число в шестнадцатиричной системе исчисления, в котором закодированы:

0-3 байты — временная метка (когда объект был создан).

4-6 байты — идентификатор машины на котором запущена MongoDB (необходимо того, когда ваша БД разбита на нескольких машинах и ID документов на всех машинах должны быть уникальны).

7-8 байты — ID процесса

9-11 байты — счетчик (у каждого следующего документа здесь записывается число на 1 больше, чем у предыдущего).

Таким образом 12-байтный ключ дает 100% гарантию, что в БД не будет двух документов с одинаковым ID даже при большой скорости поступления новых данных, когда документы могут создаваться одновременно и на большом количестве серверов.

Если вам понадобится обновить определенный документ, то для этого существует специальный метод .update():

db.posts.findOne({ title: "Title for post # 6" })
//{ "_id" : ObjectId("4ef64c526e06ee4cec3dab53"), "title" : "Title for post # 6", "content" : "Content for post # 6" }

db.posts.update({ title: "Title for post # 6" }, {title:"New title"});

db.posts.findOne({ title: "New title" });
//{ "_id" : ObjectId("4ef64c526e06ee4cec3dab53"), "title" : "New title" }

Как видите, .update() делает не совсем то, что нам нужно, он не заменил значение ключа title документа, но полностью переписал документ. Для того, чтобы заменить конкретный ключ документа, но и оставить остальные мы можем делать так:

post = db.posts.findOne({ title: "New title" });
//{ "_id" : ObjectId("4ef64c526e06ee4cec3dab53"), "title" : "New title" }

post.title
/*New title*/

post.content = "Lorem ipsum ..."
//Lodem ipsum ...

post
/*{
"_id" : ObjectId("4ef64c526e06ee4cec3dab53"),
"title" : "New title",
"content" : "Lorem ipsum ..."
}*/

db.posts.update({ title: "New title" }, post);

db.posts.findOne({ title: "New title" });
/*{
"_id" : ObjectId("4ef64c526e06ee4cec3dab53"),
"title" : "New title",
"content" : "Lodem ipsum ..."
}*/

Чтобы удалить документ из коллекции необходимо использовать метод .remove():

db.posts.remove({title:"New title"});

Работа в консоли с MongoDB очень проста, если вы хоть немного знаете JavaScript.

CRUD
Закрепляем материал.

// Create
blog = { "url" : "http://rubydev.ru", "name" : "RubyDev" }
db.sites.insert(blog);

// Read
db.sites.findOne({name:"RubyDev"})
/*{
"_id" : ObjectId("4ef663856e06ee4cec3dab59"),
"url" : "http://rubydev.ru",
"name" : "RubyDev"
}*/

// Update
blog.description = "Изучаем Ruby и Rails вместе!"
//Изучаем Ruby и Rails вместе!
db.sites.update({name:"RubyDev"}, blog);

// Delete
db.sites.remove({name:"RubyDev"});

Успехов вам в разработке!

Tags: , , ,

Responses

  1. tankard says:

    декабря 25, 2011 at 08:00 (#)

    В инете полно статей по базовому взаимодействую с монго и ей подобными. Но практически нет информации зачем все это нужно. Чем nosql решения отличаются от sql и каково их применение на практике, а не просто поиграться в консоли.

  2. Loki says:

    декабря 25, 2011 at 12:24 (#)

    В каких случая имеет смысл использовать документоориентированную бд? Только если синтаксис больше нравится?

  3. admin says:

    декабря 25, 2011 at 18:04 (#)

    Loki, нет, синтаксис тут скорее как побочное явление, просто такой синтаксис запросов более удобен для работы с документами. Документ — это по сути обыкновенный объект, а коллекция — массив документов.

    Профит в следующем:
    1. Простота. С цельным куском данных (это я так документы обзываю) проще работать, чем с данными разбитыми по нескольким таблицам (и, как правило, быстрее).

    2. Скорость aka производительность. Как правило документо-ориентированные хранилища данных более производительны в сравнении с реляционными.

    3. Гибкость. schema-free позволяет добавлять документам абсолютно любые ключи и значения.

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

    5. Простота администрирования. Зная JavaScript можно писать очень полезные скрипты для обслуживания БД.

    Опять-таки, документо-ориентированные БД, как и NoSQL (not only SQL) решения в целом не являются панацеей, но только альтернативой. Чаще всего в серьезных проектах совмещают несколько типов баз данных. Тот же Memcached относится к key-value storage — решениям и активно используется повсеместно, как вместе с MySQL, PostgreSQL и т.д., так и с MongoDB.

  4. Vitaly Pushkar says:

    декабря 25, 2011 at 22:15 (#)

    Мне очень нравится использовать MongoDB в Ruby on Rails проектах, поскольку меня всегда бесила необходимость пользоваться миграциями для изменения структуры данных, а тут этой проблемы нету.

Leave a Response

Для подсветки кода используйте BB - коды: [language]...[/language], где language может быть: ruby, javascript, css, html.