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, skip и sort
Для того, чтоб получить ограниченное количество документов по запросу используется команда limit:
Вернёт первых 3-х пользователей. Для того, чтоб пропустить несколько документов и получить все остальные используется команда skip:
Получаем всех пользователей, кроме первых трёх. Для сортировки используется команда sort. Сортировка может быть по возрастанию (1) и по убыванию (- 1). Сортировка может производится по нескольким ключам в порядке их приоритета:
Все эти три команды можно использовать вместе:
db.stock.find( { "desc" : "mp3" } ).limit(50).skip(50).sort( { "price" : -1 } ); Использование команды skip с большими значениями работает не особо быстро. Рассмотрим это на примере пагинации:
Самый простой способ сделать пагинацию это в первый раз вернуть фиксированное количество документов, а потом каждый раз смещать диапазон на это значение
но это будет работать довольно медленно. Допустим мы будет делать выборку относительно даты создания документа:
Сортируем по убыванию и берём первые 100. Чтоб не делать skip мы можем получить дату последнего документа и сделать запрос уже относительно этой даты:
Так можно избежать использования команды skip для больших значений.
Оператор SQL | MongoDB | Описание |
---|---|---|
< | $lt | меньше |
<= | $lte | меньше или равно |
> | $gt | больше |
>= | $gte | больше или равно |
<> | $ne | не равно |
NOT | $not | отрицание |
EXISTS | $exists | проверка существования поля |
OR | $or | или |
NOT OR | $nor | не или |
RLIKE, REGEXP | $regex | соответствие регулярному выражению |
LIKE | $elemMatch | соответствие всех полей вложенного документа |
- | $size | соответствие размеру массива |
- | $type | соответствие, если поле имеет указанный тип |
Работа со списками
Оператор SQL | MongoDB | Описание |
---|---|---|
IN | $in | входит в список |
NOT IN | $nin | не входит в список |
ALL | $all | одновременное совпадение набора элементов |
Оператор $in извлекает записи для которых заданное значение совпадает хотя бы с одним из списка. Ниже выводится запрос, извлекающий записи, поле title которых совпадает с одним из значений в списке ['MongoDB', 'MySQL']:
Для обновления используется метод update, первый аргумент которого определяет список обновляемых документов, второй — как отобранные документы модифицируются. Следующая команда добавляет в документ с названием "MongoDB" дополнительное поле nosql, со значением "true":
db.mybase.update({"title": "MongoDB"}, {$set: {nosql: "true"}}) db.mybase.find() { "_id" : ObjectId("51eb9bb1303d105141c7d74b"), "title" : "MySQL" } { "_id" : ObjectId("51eb9bb1303d105141c7d74c"), "title" : "PostreSQL" } { "_id" : ObjectId("51eb9bb2303d105141c7d74e"), "title" : "MS SQL" } { "_id" : ObjectId("51eb9bb2303d105141c7d74f"), "title" : "Oracle" } { "_id" : ObjectId("51eb9bb1303d105141c7d74d"), "nosql" : "true", "title" : "MongoDB" }
Если обновлению подвергается только одно поле, следует обязательно использовать оператор $set. Если его опустить, вместо обновления поля, будет обновлен весь документ:
db.mybase.update({"title": "MongoDB"}, {nosql: "true"}) db.mybase.find() { "_id" : ObjectId("51eba53f303d105141c7d751"), "title" : "MySQL" } { "_id" : ObjectId("51eba53f303d105141c7d752"), "title" : "PostreSQL" } { "_id" : ObjectId("51eba53f303d105141c7d754"), "title" : "MS SQL" } { "_id" : ObjectId("51eba53f303d105141c7d755"), "title" : "Oracle" } { "_id" : ObjectId("51f9582829b045085952815f"), "nosql" : "true" }
Для удаления дополнительного поля nosql, вместо оператора $set, следует подставить $unset
> db.mybase.update({"title": "MongoDB"}, {$unset: {nosql: "none"}}) > db.mybase.find({"title": "MongoDB"}) { "_id" : ObjectId("51eb9bb1303d105141c7d74d"), "title" : "MongoDB" }
Для того, чтобы добавить ключевое слово в массив тэгов tags базы данных articles следует воспользоваться оператором $addToSet
db.articles.update({tags: "Redis"}, {$addToSet: {tags: "Обзор"}})
Если запросить состав текущей базы данных при помощи метода find(), можно заметить, что обновился только один документ из двух, которые имеют ключевое слово "Redis". Для того, чтобы обновить все документы, следует передать четвертому параметру метода update() значение true, что заставит MongoDB обновить все найденные документы
db.articles.update({tags: "Redis"}, {$addToSet: {tags: "Обзор"}}, false, true)
Ниже приводится сводная таблица по операторам, используемым совместно с методом update()
Оператор | Описание |
---|---|
$set | обновление или создание поля |
$unset | удаление поля |
$inc | увеличение значения поля на заданное число |
$pop | удаляет последний (или первый) элемент массива |
$pushAll | помещает несколько элементов в массив |
$push | помещает новый элемент в массив |
$addToSet | помещает новый элемент в массив (исключаются дубликаты) |
$pull | удаляет из массива значение (при его наличии) |
$pullAll | удаляет из массива все подходящие значения |
Полностью удалить документы из текущей базы данных можно при помощи метода remove()
db.mybase.remove()
Точно также, как и другие методы, в качестве параметра метод может принимать селекторы, например, удалить все записи в ключом nosql равным "true" можно при помощи следующей команды