Хоть и некоторые писали относительно моего предыдущего топика MongoDB: Создание, обновление и удаление документов, что это пересказ офф. документации, я с этим не полностью согласен. Мне показалось, что информация в нём оказалось кому-то полезной, поэтому выкладываю продолжение.
Find — аналог SELECT в MySQL. Используется для выборки документов из MongoDB. Возвращает массив документов в виде коллекции, если документов нет — пустую коллекцию. Пример:
Вернёт всех пользователей из коллекции.
Вернёт всех пользователей, у которых возраст равен 27.
Можно указывать несколько параметров, например, вот так:
Иногда бывает необходимо получить какие то конкретные поля из документов. В этом случае запрос выглядит так:
В итоге получим всех пользователей только с полями «username» и «email» + поле "_id", которое возращается всегда по умолчанию. Если поле "_id" или какое-либо другое не нужно, мы можем это указать вот так:
Операторы: $lt — меньше, $lte — меньше или равно, $gt — больше, $gte — больше или равно, $ne — не равно.
Примеры использования:
Получаем всех пользователей, возраст которых больше 18 и меньше 30
Получаем всех пользователей, «username» которых не равен “joe”
Допустим, у нас коллекция хранит лотерейные билеты с номерами и нам нужно найти только те, в которых есть победившие номера 390, 754, 454. В таком случае мы используем оператор $in:
т.е. билет должен содержать один из этих номеров.
Противоположным оператору $in является $nin. Он, по аналогии, получает только те билеты, где нет, указанных выше, номеров.
Оператор $or используется при запросах, когда нужно выбрать документы по совпадению одному из значений. Например, нам нужно выбрать все билеты с номером 547 или где поле «winner» равно true:
Оператор $mod используется для выборки ключей, значения которых делятся на первый аргумент и остаток от деления получается равным второму аргументу. Звучит непонятно, вот более наглядно:
Такой запрос вернёт всех пользователей, «user_id» которых равен 1, 6, 11, 16 и так далее.
Чтоб получить всех пользователей, кроме вышеуказанных можно использовать оператор $not:
Получим пользователей с «user_id» 2, 3, 4, 5, 7, 8, 9, 10, 12 и так далее.
Существует также оператор для проверки существует ли какой то ключ или нет — $exist
Так можно выбрать все документы коллекции, где существует ключ “z” и он равен null.
Все мы знаем, что регулярные выражения очень мощная штука. MongoDB использует Perl-совместимые регулярные выражения.
Вот так можно найти всех пользователей с именем joe или Joe:
Вообщем есть где разгуляться. Есть куча сервисов для того же javascript’a, где можно писать и проверять свои регулярки.
Допустим есть у нас коллекция food и мы туда вставляем документ с массивом фруктов
То вот такой запрос
успешно его найдёт.
Если нужно выбрать документы больше, чем по одному элементу массива, то мы можем использовать оператор $all
Такой запрос вернёт все документы, в массиве фруктов которых, есть и яблоки, и бананы.
Получить документы по полному совпадению элементов в массиве можем так:
Есть у нас блог, в нём хранятся комментарии. Мы хотим получить первые 10 комментариев. На помощь нам приходит оператор $slice:
findOne — работает аналогично find, но возвращает первый совпавший документ.
Если нужно получить последние 10 комментариев пишем вот так:
Также $slice умеет получать документы из середины:
в этом случае будет пропущено 23 начальных элемента и вернутся элементы с 24 по 34, если это возможно
Для того, чтоб получить ограниченное количество документов по запросу используется команда limit:
Вернёт первых 3-х пользователей.
Для того, чтоб пропустить несколько документов и получить все остальные используется команда skip:
Получаем всех пользователей, кроме первых трёх.
Для сортировки используется команда sort. Сортировка может быть по возрастанию (1) и по убыванию (- 1). Сортировка может производится по нескольким ключам в порядке их приоритета:
Все эти три команды можно использовать вместе:
Использование команды skip с большими значениями работает не особо быстро. Рассмотрим это на примере пагинации:
Самый простой способ сделать пагинацию это в первый раз вернуть фиксированное количество документов, а потом каждый раз смещать диапазон на это значение
но это будет работать довольно медленно. Допустим мы будет делать выборку относительно даты создания документа:
Сортируем по убыванию и берём первые 100. Чтоб не делать skip мы можем получить дату последнего документа и сделать запрос уже относительно этой даты:
Так можно избежать использования команды skip для больших значений.
По сути это основные вещи относительно запросов в MongoDB. Надеюсь это кому-нибудь пригодится.
Find — аналог SELECT в MySQL. Используется для выборки документов из MongoDB. Возвращает массив документов в виде коллекции, если документов нет — пустую коллекцию. Пример:
> db.users.find();
Вернёт всех пользователей из коллекции.
> db.users.find( { age: 27 } );
Вернёт всех пользователей, у которых возраст равен 27.
Можно указывать несколько параметров, например, вот так:
> db.users.find( { username: “joe”, age: 27 } );
Иногда бывает необходимо получить какие то конкретные поля из документов. В этом случае запрос выглядит так:
> db.users.find( { }, { username: 1, email: 1 } );
В итоге получим всех пользователей только с полями «username» и «email» + поле "_id", которое возращается всегда по умолчанию. Если поле "_id" или какое-либо другое не нужно, мы можем это указать вот так:
> db.users.find( { }, { username: 1, email: 1, _id: 0 } );
Запросы с условием
Операторы: $lt — меньше, $lte — меньше или равно, $gt — больше, $gte — больше или равно, $ne — не равно.
Примеры использования:
Получаем всех пользователей, возраст которых больше 18 и меньше 30
> db.users.find( { age: { $gte: 18, $lte: 30 } } );
Получаем всех пользователей, «username» которых не равен “joe”
> db.users.find( { username: { $ne: “joe” } } );
Допустим, у нас коллекция хранит лотерейные билеты с номерами и нам нужно найти только те, в которых есть победившие номера 390, 754, 454. В таком случае мы используем оператор $in:
> db.users.find( { numbers: { $in: [ 390, 754, 454 ] } } );
т.е. билет должен содержать один из этих номеров.
Противоположным оператору $in является $nin. Он, по аналогии, получает только те билеты, где нет, указанных выше, номеров.
Оператор $or используется при запросах, когда нужно выбрать документы по совпадению одному из значений. Например, нам нужно выбрать все билеты с номером 547 или где поле «winner» равно true:
> db.users.find( { $or: [ { tickect_number: 547 }, { winner: true } ] } );
Оператор $mod используется для выборки ключей, значения которых делятся на первый аргумент и остаток от деления получается равным второму аргументу. Звучит непонятно, вот более наглядно:
> db.users.find( { user_id: { $mod: [ 5, 1 ] } } );
Такой запрос вернёт всех пользователей, «user_id» которых равен 1, 6, 11, 16 и так далее.
Чтоб получить всех пользователей, кроме вышеуказанных можно использовать оператор $not:
> db.users.find( { user_id: { $not: { $mod: [ 5, 1 ] } } } );
Получим пользователей с «user_id» 2, 3, 4, 5, 7, 8, 9, 10, 12 и так далее.
Существует также оператор для проверки существует ли какой то ключ или нет — $exist
> db.c.find({"z" : {"$in" : [null], "$exists" : true}});
Так можно выбрать все документы коллекции, где существует ключ “z” и он равен null.
Регулярные выражения
Все мы знаем, что регулярные выражения очень мощная штука. MongoDB использует Perl-совместимые регулярные выражения.
Вот так можно найти всех пользователей с именем joe или Joe:
> db.users.find( { "name" : /^joe$/i } );
Вообщем есть где разгуляться. Есть куча сервисов для того же javascript’a, где можно писать и проверять свои регулярки.
Запросы в массивах
Допустим есть у нас коллекция food и мы туда вставляем документ с массивом фруктов
> db.food.insert( { "fruit" : [ "apple", "banana", "peach" ] } );
То вот такой запрос
> db.food.find({"fruit" : "banana"});
успешно его найдёт.
Если нужно выбрать документы больше, чем по одному элементу массива, то мы можем использовать оператор $all
> db.food.find( { fruits: { $all : [ "apple", "banana" ] } } );
Такой запрос вернёт все документы, в массиве фруктов которых, есть и яблоки, и бананы.
Получить документы по полному совпадению элементов в массиве можем так:
> db.food.find( { fruits: [ "apple", "banana", "peach" ] } );
Есть у нас блог, в нём хранятся комментарии. Мы хотим получить первые 10 комментариев. На помощь нам приходит оператор $slice:
> db.blog.posts.findOne( { }, { "comments" : { "$slice" : 10 } } );
findOne — работает аналогично find, но возвращает первый совпавший документ.
Если нужно получить последние 10 комментариев пишем вот так:
> db.blog.posts.findOne( { }, { "comments" : { "$slice" : -10 } } );
Также $slice умеет получать документы из середины:
> db.blog.posts.findOne( { }, { comments : { "$slice" : [ 23, 10 ] } });
в этом случае будет пропущено 23 начальных элемента и вернутся элементы с 24 по 34, если это возможно
Команды limit, skip и sort
Для того, чтоб получить ограниченное количество документов по запросу используется команда limit:
> db.users.find().limit(3);
Вернёт первых 3-х пользователей.
Для того, чтоб пропустить несколько документов и получить все остальные используется команда skip:
> db.users.find().skip(3);
Получаем всех пользователей, кроме первых трёх.
Для сортировки используется команда sort. Сортировка может быть по возрастанию (1) и по убыванию (- 1). Сортировка может производится по нескольким ключам в порядке их приоритета:
> db.users.find().sort( { username : 1, age : -1 } );
Все эти три команды можно использовать вместе:
> db.stock.find( { "desc" : "mp3" } ).limit(50).skip(50).sort( { "price" : -1 } );
Использование команды skip с большими значениями работает не особо быстро. Рассмотрим это на примере пагинации:
Самый простой способ сделать пагинацию это в первый раз вернуть фиксированное количество документов, а потом каждый раз смещать диапазон на это значение
> var page1 = db.foo.find(criteria).limit(100)
> var page2 = db.foo.find(criteria).skip(100).limit(100)
> var page3 = db.foo.find(criteria).skip(200).limit(100)
но это будет работать довольно медленно. Допустим мы будет делать выборку относительно даты создания документа:
> var page1 = db.foo.find().sort( {"date" : -1} ).limit(100);
Сортируем по убыванию и берём первые 100. Чтоб не делать skip мы можем получить дату последнего документа и сделать запрос уже относительно этой даты:
var page2 = db.foo.find( { "date" : { "$gt" : latest.date } } );
Так можно избежать использования команды skip для больших значений.
По сути это основные вещи относительно запросов в MongoDB. Надеюсь это кому-нибудь пригодится.