Записки Вредного программиста

enjoy, motherfuckers ;)

MongoDb и PHP

В данной заметке вы узнаете что такое NoSQL (MongoDB), научитесь устанавливать MongoDB сервер и взаимодействовать с ним на PHP.

NoSQL – что за странная аббревиатура?

Наверное, какждый из вас уже слышал эту аббревиатуру, может даже вы “щупали” ее на зубок, а может и используете ее в своих проектах на продакшн серверах. Данная технология в момент ее появления наделала много шуму, легко втиснувшись и отобрав кусок хлеба у реляционных баз данных. NoSQL термин означает что это не только (not only) SQL, хотя на первый взгляд кажется, что это не SQL (no). Термин означает множество технологий работы с базами данных в обход стандартной реляционной модели. Данные могут храниться в виде пар ключ-значение, деревьев или документов. Мы с вами рассмотрим последнее.

Описание документо-ориентированных хранилищ

В данной системе управления базами данных единицей хранения информации является некий документ, хранящийся в виде пар ключ-значние и имеющих некие связи.

Что же такое MongoDB?

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

  1. Концепция базы данных не отличима от понятий базы данных в реляционных СУБД. MongoDB также может содержать ноль или более баз данных, которые являются контейнером верхнего уровня.
  2. База данных может содрежать ноль или более коллекций. Коллекциями в контексте СУРБД (здесь и далее система управления реляционными базами данных) являются таблицы.
  3. Коллекция может содрежать в себе документы. В СУРБД это строки.
  4. Документ может состоять из разного количества полей. Если проводить аналогию с реляционной моделью, то это конечно же столбец.
  5. Индексы есть и в MongoDB, и в СУРБД, функции их почти неотлимы.
  6. Курсоры есть в MongoDB, но прямого аналога в реляционной модели нет. Важно понять, что, когда вы запрашиваете MongoDB вернуть вам определенные данные, Mongo возвращает курсор, с помощью которого мы можем подсчитать или пропустить некоторые документы, без нагрузки на сервер.

Установка MongoDB

Подробная информация об установке широко представлена на официальном сайте, поэтому не будем заострять внимание на этом разделе. Я затрону лишь основные моменты, чтобы начать работу. Пройдемся по шагам, чтобы ее завершить:

  1. Заходим на официальную страницу загрузки, скачиваем подходящую скомпилированную версию.
  2. Распаковываем архив куда угодно и заходим в папку bin. mongod – сервер, mongo – клиентская оболочка – с этими двумя исходниками мы и будем проводить большую часть времени.
  3. Создаем текстовый файл в папке bin, пусть называться он будет mongod.conf
  4. Записываем одну строку во вновь созданный файл dbpath=ПУТЬ-ГДЕ-ВЫ-ХОТИТЕ-ЧТОБЫ-ЛЕЖАЛА-БАЗА-ДАННЫХ. К примеру, на Windows вы можете написать dbpath=c:\mongodb\data, под Линуксом dbpath=/etc/mongodb/data. Указанный путь должен сущестовать (позаботьтесь об этом).
  5. Запустите из папки bin файл mongod с параметром **—config /путь/к/конфигу/mongodb.conf.

Установка завершена. Чтобы это проверить запустите в командной строке клиент (mongo), которые должен автоматически соединиться с запущенным сервером и отобразить приглашение. Попробуйте ввести help или db.version(). Пока оставим наш клиент и перейдем к PHP.

PHP и MongoDB

MongoDB на данный момент имеет поддержку почти всех популярных языков программирования, таких как C++, Erlang, Java, Javascript, Perl, Python и PHP. На последнем мы и остановимся.

Описание расширения

Я не буду приводить пример установки раширений для PHP. В нем нет ничего нетривиального. Лучше заострю внимание на чем-нибуь более интересным, чтобы вы после прочтения данной заметки легко написать свое первое приложение с использованием MongoDB. Полное описание расширения вы можете на странице официального руководства (http://www.php.net/manual/en/book.mongo.php).

Соединение

Начнем с соединения (сервер на данный момент должен быть запущен). Если мы экспериментируем на своей локальной машине, то все просто.

1
2
3
<?php
      $mongo = new Mongo(); // соединяемся с сервером
      $db = $mongo->database; // выбираем базу данных

Если же вы используете MongoDB на выделенном хостинге или по каким-то другим причинам вам требуется авторизация, то данный пример немного усложнится.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 array(
      'host' => 'mongodb.example.com',
      'port' => '27017',
      'username' => 'mongodb-user',
      'password' => 'SECRET-PASSWORD',
      'dbname' => 'DATABASE-NAME'
  )
);

$collectionName = 'COLLECTION-NAME';

$mongo = new Mongo(
  "mongodb://{$options['db']['username']}:{$options['db']['password']}@{$options['db']['host']}:{$options['db']['port']}/{$options['db']['dbname']}"
);

$collection = $mongo->$options['db']['dbname']->$collectionName;

Данные пляски очень похожи на DSN, которые повсеместно используется с PDO.

Запись

Соединяться с сервером мы уже научились, также как и выбирать коллекцию. Кстати, если нет коллекции, ничего страшного, если вы будете вносить данные в несуществующую коллекцию, то заботливый Mongo ее для вас создаст. Еще раз убеждаюь, что MongoDB создана для лентяев, которые хотят сосредоточиться только на важных вещах, а на не плясках с бубном. :)

1
2
3
4
5
6
7
$collection->insert(
  array(
      'title' => 'Simple Title',
      'alias' => 'about',
      'content' => 'Lorem Ipsum',
      'images' => array('image1.jpg', 'image2.jpg')), // вставляем какие угодно данные, хоть массивы
  array("safe" => 1)); // данный параметро сообщает MongoDB проследить за успешностью вставки, обычно этот параметр отключен
Выборка
1
2
$content = $collection->findOne(array('alias' => 'about')); // находим одну запись, удоволетворяющая условию {alias: 'about'}
var_dump($content);

Выборка происходит почти также как в реляционных базах данных после слова WHERE (select * from COLLECTION-NAME WHERE alias = ‘about’ LIMIT 1). Разработчики предусмотрели множество плюшек при выборке, но всех их рассмотреть в данной вводной заметке не представляется возможным, поэтому расскажу еще о выборке с участием регулярных выражений и отклоняюсь.

1
2
3
4
5
6
$cursor = $collection->find(array('word' => new MongoRegex("/{$mask}/ig")))->limit(50);

$words = array();

foreach ($cursor as $o)
  $words[] = $o;

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

Изменение

Изменение данных в документах чуть более обширный раздел, заключающий в себе и выборку и запись новых данных. Но не все так сложно, как я малюю. Начну с примера.

1
$collection->update(array('alias' => 'about'), array('$set' => array("title" => 'In MongoDB we trust')));

Данная запутанная с первого взляда запись на самом деле проста, если разбить ее на составляющие. Первый параметр в методе update() отвечая за выборку, т.е. критерии выборки, второй параметр, как будем менять. В данном случае мы установим ($set) заголовок в новый. Отличные от $set параметры вы можете найти в документации к MongoDB. Аналог в виде SQL мог бы выглядеть так

1
update COLLECTION-NAME set title = 'In MongoDB we trust' where alias = 'about'

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

Заключение

В первую очередь вам следует понять, что волшебной таблетки не существует. Любое решение, каким бы оно не казалось со стороны гибким и легким, имеет свои плюсы и минусы. Если вам не нужно хранить статистические данные, которые размазаны по десятками а то и сотням таблиц со сложными связями, вряд ли вам подойдет NoSQL решения. Если же данные легко подвергаются денормализации, то смело выбирайте NoSQL из-за скорости и удобности работы.

Комментарии