Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Databases
Code

Начало работы с MongoDB - Часть 2

by
Difficulty:IntermediateLength:LongLanguages:

Russian (Pусский) translation by Sergey Zhuk (you can also view the original English article)

Готовы продолжить изучение MongoDB, одной из самых крутых технологий в вебе? Во второй части серии статей мы перейдем от основ к более продвинутым запросам, условным операторам и MapReduce.

Выходим за пределы основ

Ранее мы уже рассмотрели базовый функционал и начало работы с MongoDB, одной из лучших реализаций NoSQL. Мы увидели как устанавливать ее, создавать новую базу, а затем выполнять базовые запросы в ней:

  • поиск
  • изменение
  • удаление

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

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

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

  • Расширенные запросы
  • MapReduce

Расширенные запросы

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

  • Условные операторы
  • Регулярные выражения

Каждая из этих возможностей предоставляет нам более мощный контроль над запросами и соответственно данными, которые мы можем достать из нашей MongoDB базы.

Условные операторы

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

  • $lt - значение должно быть меньше
  • $gt - значение должно быть больше
  • $lte - значение должно быть меньше или равно
  • $gte - значение должно быть больше или равно 
  • $in - значение должно содержаться в наборе
  • $nin - значение НЕ должно содержаться в наборе
  • $not - значение не должно быть равно

Рассмотрим каждое из них в действии. Откроем терминал и воспользуемся базой из предыдущей статьи. Чтобы облегчить эту статью, мы внесем незначительные изменения в эту базу данных. Добавим каждому документы в нашей коллекции атрибут age. Чтобы сделать это, выполним следующий запрос:

Если все выполнилось успешно, то после выполнения 'find all' вы получите такой вывод:

$lt/$lte

Теперь найдем всех актеров моложе 40 лет. Для этого выполняем такой запрос:

После его выполнения получаем:

Как на счет тех, кто моложе 40 лет включительно? Чтобы получить результат выполним такой запрос:

Он вернет следующий список:

$gt/$gte

Теперь давайте найдем всех акторов, которые старше 47. Выполним следующий запрос, чтобы получить такой список:

А затем вы получите такой вывод:

Как на счет включая 40?

Так как есть только один человек старше 47, то результат не изменится.

$in/$nin

Как найти данные по набору критерий? Первые из них были удобными, но весьма тривиальными.  Теперь давайте найдем тех, кто является актером или разработчиком. С этим запросом мы получим такой список (для удобства чтения мы ограничили кол-во возвращаемых полей в документе).

Этот запрос вернет следующий вывод:

Видно что мы можем получить  обратное, просто используя $nin.

Давайте еще немного поиграемся с различными комбинациями операторов. Допустим нам нужны мужчины разработчики моложе 40 лет.

Звучит сложно, но с помощью операторов, которые мы уже использовали, это довольно легко. Давайте попробуем и вы сами в этом убедитесь. Обратите внимание на этот запрос:

Видно, что мы указали в выражении $or, что пол может быть мужским или профессия - разработчик, а затем добавили and условие, что возраст должен быть больше чем 40.

И получаем следующие результаты:

Регулярные выражения

Теперь я уверен, что вы не остановитесь на этом. Я же обещал вам немного более сложных запросов и продвинутый функционал. Так что продолжим наше изучение дальше с регулярными выражениями. Допустим нам нужно найти пользователей, у которых имя начинается с 'ma' или 'to', а фамилия начинается с 'se' или 'de'. Как нам такое сделать?

Рассмотрим этот запрос с использованием регулярных выражений:

Результаты его выполнения:

Рассмотрим этот запрос более внимательно. Сначала мы выполняем regex с именем.

//i означает, что выполняем регистро-независимую операцию.

(ma|to)* означает, что начало имени должно быть строкой либо 'ma' либо 'to'.

* в конце означает любые символы. И когда мы все соединим то получим имена, у которых в начале содержится либо 'ma' либо 'to'. В регулярном выражении для фамилии мы сделаем тоже самое.

Не совсем понятно? Тогда давайте попробуем еще одно. Соединим регулярное выражение с одним из условных операторов. Допустим нам нужно найти всех с именем james или jamie, кто является американцем и актером женского пола. Как нам это сделать? Что ж, рассмотрим ниже, как это можно реализовать:

Данное регулярное выражение совпадет для таких комбинаций как: james, jamie, jamee и тд. Знак вопроса означает один символ, не важно a-z, A-Z ил 0-9. Затем, как и раньше, * означает все что угодно, что идет после 'e'. Затем мы используем условные операторы, чтобы ограничить возвращаемые результаты. Следует заметить, что так как мы используем регистро-независимый оператор i, то запросы не будут использовать индексы. Но для целей этого примера, это нормально.

Вот результаты этого запроса:

MapReduce

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

Этот термин состоит из двух частей: Map и Reduce. Map создает задачи, которые в последствии могут быть переданы различным узлам системы для выполнения Recuce компонента. Затем Reduce собирает ответы с каждого узла, а затем возвращает результат, который может быть использован другими частями для получений итогового результат.

Если вам нужно более подробное определение, то вот что говорит об этом Wikipedia:

MapReduce — это фреймворк для вычисления некоторых наборов распределенных задач с использованием большого количества компьютеров (называемых «нодами»), образующих кластер. Работа MapReduce состоит из двух шагов: Map и Reduce, названных так по аналогии с одноименными функциями высшего порядка, map и reduce.

На Map-шаге происходит предварительная обработка входных данных.  Для этого один из компьютеров (называемый главным узлом — master node) получает входные данные задачи. Затем разделяет их на части и передает другим компьютерам (рабочим узлам — worker node) для предварительной обработки.

На Reduce-шаге происходит свёртка предварительно обработанных данных. Главный узел получает ответы от рабочих узлов и на их основе формирует результат — решение задачи, которая изначально формулировалась.

Пример MapReduce

Рассмотрим простой пример. Попробуем проанализировать наш простой набор данных и найти общее количество всех женщин в группе. Правда это очень упрощенный пример, но заложит основу для понимания, как на практике работает MapReduce.

Map функция

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

Мы получим результат похожий на это:

Reduce функция

Наша reduce функция берет выходные данные из map функции и использует их для получения общего количества для каждого пола. Рассмотрим данную reduce функцию.

Выполнение MapReduce

Теперь соединим все вместе с помощью вызова функции mapReduce в нашей текущей базе данных. Мы передаем переменные map и reduce, которые создали до этого, вызывая наши map и reduce функции и указываем имя коллекции, в которой будет сохранен результат, например 'gender'.  Результатом вызова функции mapReduce является коллекция в нашей текущей базе данных, поэтому мы можем обращаться к ней точно так же, как и любой другой коллекции. Взгляните на код ниже:

Вывод результатов

После выполнения Map-Reduce мы можем получить доступ к результатам как к простой коллекции, используя функцию find, как показано ниже.

Здесь у нас результаты всего для каждого пола: 2 для женщин и 5 для мужчин, что совпадает с нашим набором данных. Но что если нам потребуется фильтрация женщин в группе. Это легко сделать. Нам потребуется всего лишь использовать условия в запросе, чтобы это сделать. К счастью для нас, это выглядит уже знакомо. Взгляните на этот запрос.

Теперь когда мы показываем вывод, то он будет выглядеть так:

Существует еще набор других параметров, которые вы можете передать в функцию mapReduce чтобы в затем кастомизировать результаты.

  • sort - сортирует возвращаемый результат
  • limit - ограничивает количество возвращаемых результатов
  • out - имя коллекции, в которой будут сохранены результаты
  • finalise - можно передать функцию, которая будет выполнена в конце
  • scope - определяет переменные, которые могут быть использованы в map, reduce и finalise функции.
  • jsMode - позволяет пропустить промежуточный шаг (между map и reduce) для конвертации назад в JSON формат
  • verbose - собирает статистику о процессе выполнения

Подведем итоги

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

Мы рассмотрели условные операторы: $lt, $gt, $lte, $gte, $in, $nin, $not и ознакомились с MapReduce. Я надеюсь, что вы узнали много нового из этих статей и продолжите дальше изучение mongoDB.

Advertisement
Advertisement
Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.