NoSQL. PHP. Реализуем хитрый OR
24 февраля, 2011
Допустим у нас имеется коллекция сайтов, и, внутри этой коллекции хранятся данные о пользователях сайта, и их правах в этом сайте.Приведу один объект из коллекции, но их у нас много:
Задача: выбрать документы из данной коллекции, где определённый user_id находится или в первом уровне(является владельцем) или в коллекции пользователей этого сайта (является назначенным пользователем и его права определяются дополнительно).
В обычном sql у нас бы не было так вкусно расположенных данных, а было бы 2-3 таблицы связанные таблицами объединяющими их id (много ко многим) и решением было бы сделать крутой джойн или несколько запросов.
Решение в NoSQL (MongoDB, PHP):
//Подконнектимся $this->connection = new Mongo('localhost:27017'); //Дёрним нужную базу $this->db = $this->connection->mydb; //Что будем искать $user_id='fabe6e3dab8c63bb28a27b98c5c15554'; //Будем искать или сразу в первом уровне user_id или users.user_id. //Немного непривычная форма формирования условия, но это адапрированный json, через массивы //Примерно: or (_первое выражение_, _второе выражение_) $data=array('$or'=>array(array('users.user_id'=>$user_id),array('user_id'=>$user_id))); //Переберём их по-порядку, т.к. они объекты $cursor=$this->db->sites->find($data); $sites=array(); foreach ($cursor as $site) { //Сформируем массив таких сайтов удовлетворяющих условию $sites[]=$site; } |
Согласитесь, красивое и удобное решение?=)
Обратите внимание, что документов в коллекции пользователей разные атрибуты.
Отлично когда все умещается в один запрос 🙂 Столько уровней внутри массива $data дают не слабую гибкость, надо уже начать создавать сайты с NoSQL, интересно какой прирост производительности будет если переписать все мои старые решения c JOIN’ами на NoSQL?
NoSQL насколько знаю между коллекциями данные при запросе объединяет с трудом. Решение будет не столь очевидное как выше. Так что не всё будет разумным переносить на NoSQL. ну и архитектуру базы нужно будет менять с учётом особенностей проекта. А работает шустро.
интересно!
очень полезная заметка.спасибо. у меня есть вопрос. никак не могу найти на него ответ.может бы вы мне поможете.в вашем примере вы формируете массив сайтов, на основе данных о пользователях. а как мне если я знаю user_id и site_id вывести список прав нужного мне пользователя?
а какова структура данных коллекции?
или нужно для моего примера вывести по конкретному сайту и конкретному юзеру его права?
На вскидку вроде так: $data=array(‘site_id’=>$site_id, ‘users.user_id’=>$user_id);