ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 12.01.2024
Просмотров: 45
Скачиваний: 1
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
И обратная ситуация: мы хотим найти все поля документа кроме свойства age. В этом случае в качестве параметра указываем 0:
1 | > db.persons.find({name: "Tom"}, {age: 0}) |
При этом надо учитывать, что даже если мы отметим, что мы хотим получить только поле name, поле _id также будет включено в результирующую выборку. Поэтому, если мы не хотим видеть данное поле в выборке, то надо явным образом указать: {"_id":0}
Альтернативно вместо 1 и 0 можно использовать true и false:
1 | > db.users.find({name: "Tom"}, {age: true, _id: false}) |
Если мы не хотим при этом конкретизировать выборку, а хотим вывести все документы, то можно оставить первые фигурные скобки пустыми:
1 | > db.users.find({}, {age: 1, _id: 0}) |
Запрос к вложенным объектам
Предыдущие запросы применялись к простым объектам. Но документы могут быть очень сложными по структуре. Например, добавим в коллекцию users следующий документ:
1 | > db.users.insertOne({"name": "Alex", "age": 28, company: {"name":"Microsoft", "country":"USA"}}) |
Здесь определяется вложенный объект с ключом company. И чтобы найти все документы, у которых в ключе company вложенное свойство name=microsoft, нам надо использовать оператор точку:
1 | > db.users.find({"company.name": "Microsoft"}) |
Использование JavaScript
MongoDB предоставляет замечательную возможность, создавать запросы, используя язык JavaScript. Например, создадим запрос, возвращающий те документы, в которых name=Tom. Для этого сначала объявляется функция:
1 2 | > fn = function() { return this.name=="Tom"; } > db.users.find(fn) |
Собственно только запросами область применения JavaScript в консоли mongo не ограничена. Например, мы можем создать какую-нибудь функцию и применять ее:
1 2 3 | > function sqrt(n) { return n*n; } > sqrt(5) 25 |
Использование регулярных выражений
Еще одной замечательной возможностью при построении запросов является использование регулярных выражений. Например, найдем все документы, в которых значение ключа name начинается с буквы B:
> db.users.find({name:/^B\w+/i})
Настройка запросов и сортировка
MongoDB представляет ряд функций, которые помогают управлять выборкой из бд. Одна из них - функция limit. Она задает максимально допустимое количество получаемых документов. Количество передается в виде числового параметра. Например, ограничим выборку тремя документами:
1 | > db.users.find().limit(3) |
В данном случае мы получим первые три документа (если в коллекции 3 и больше документов). Но что, если мы хотим произвести выборку не сначала, а пропустив какое-то количество документов? В этом нам поможет функция skip. Например, пропустим первые три записи:
1 | > db.users.find().skip(3) |
MongoDB предоствляет возможности отсортировать полученный из бд набор данных с помощью функции sort. Передавая в эту функцию значения 1 или -1, мы можем указать в каком порядке сортировать: по возрастанию (1) или по убыванию (-1). Во многом эта функция по действию аналогична выражению ORDER BY в SQL. Например, сортировка по возрастанию по полю name:
1 | > db.users.find().sort({name: 1}) |
Ну и в конце надо отметить, что мы можем совмещать все эти функции в одной цепочке:
1 | > db.users.find().sort({name: 1}).skip(3).limit(3) |
Поиск одиночного документа
Если все документы извлекаются функцией find, то одиночный документ извлекается функцией findOne. Ее действие аналогично тому, как если бы мы использовали функцию limit(1), которая также извлекает первый документ коллекции. А комбинация функций skip и limit извлечет документ по нужному местоположению.
Параметр $natural
Если вдруг нам надо отсортировать ограниченную коллекцию, то мы можем воспользоваться параметром $natural. Этот параметр позволяет задать сортировку: документы передаются в том порядке, в каком они были добавлены в коллекцию, либо в обратном порядке.
Например, отберем последние пять документов:
1 | > db.users.find().sort({ $natural: -1 }).limit(5) |
Оператор $slice
$slice является в некотором роде комбинацией функций limit и skip. Но в отличие от них $slice может работать с массивами.
Оператор $slice принимает два параметра. Первый параметр указывает на общее количество возвращаемых документов. Второй параметр необязательный, но если он используется, тогда первый параметр указывает на смещение относительно начала (как функция skip), а второй - на ограничение количества извлекаемых документов.
Например, в каждом документе определен массив languages для хранения языков, на которых говорит человек. Их может быть и 1, и 2, и 3 и более. И допустим, ранее мы добавили следующий объект:
1 | > db.users.insertOne({"name": "Tom", "age": "32", languages: ["english", "german"]}) |
И мы хотим при выводе документов сделать так, чтобы в выборку попадал только один язык из массива languages, а не весь массив:
1 | > db.users.find ({name: "Tom"}, {languages: {$slice : 1}}) |
Данный запрос при извлечении документа оставит в результате только первый язык из массива languages, то есть в данном случае english.
Обратная ситуация: нам надо оставить в массиве также один элемент, но не с начала, а с конца. В этом случае необходимо передать в параметр отрицательное значение:
1 | > db.users.find ({name: "Tom"}, {languages: {$slice : -1}}); |
Теперь в массиве окажется german, так как он первый с конца в добавленном элементе.
Используем сразу два параметра:
1 | > db.users.find ({name: "Tom"}, {languages: {$slice : [-1, 1]}}); |
Первый параметр говорит начать выборку элементов с конца (так как отрицательное значение), а второй параметр указывает на количество возвращаемых элементов массива. В итоге в массиве language окажется "german"
Курсоры
Результат выборки, получаемой с помощью функции find, называется курсором:
1 | > var cursor = db.users.find() |
Курсоры инкапсулируют в себе наборы получаемых из бд объектов. Используя синтаксис языка javascript и методы курсоров, мы можем вывести полученные документы на экран и как-то их обработать. Например:
1 2 3 4 5 | > var cursor = db.users.find() > while(cursor.hasNext()){ ... obj = cursor.next(); ... print(obj["name"]); ... } |
Курсор обладает методом hasNext, который показывает при переборе, имеется ли еще в наборе документ. А метод next извлекает текущий документ и перемещает курсор к следующему документу в наборе. В итоге в переменной obj оказывается документ, к полям которого мы можем получить доступ.
Также для перебора документов в курсоре в качестве альтернативы мы можем использовать конструкцию итератора javascript - forEach:
1 2 3 4 | > var cursor = db.users.find() > cursor.forEach(function(obj){ ... print(obj.name); ... }) |
Чтобы ограничить размер выборки, используется метод limit, принимающий количество документов:
1 2 3 4 5 6 | > var cursor = db.users.find() > cursor.limit(5);null; null > cursor.forEach(function(obj){ ... print(obj.name); ... }) |
Стоит обратить внимание, что, чтобы сразу же не выводить все содержащиеся в курсоре данные, после метода limit() через точку с запятой добавляется выражение null;
Используя метод sort(), можно отсортировать документы в курсоре:
1 2 3 4 5 6 | > var cursor = db.users.find() > cursor.sort({name:1});null; null > cursor.forEach(function(obj){ ... print(obj.name); ... }) |
Выражение cursor.sort({name:1}) сортирует документы в курсоре по полю name по возрастанию. Если мы хотим отсортировать по убыванию, то вместо 1 используем -1: cursor.sort({name:-1})
И еще один метод skip() позволяет пропустить при выборке определенное количество документов:
1 2 3 4 5 6 | > var cursor = db.users.find() > cursor.skip(2);null; null > cursor.forEach(function(obj){ ... print(obj.name); ... }) |
В данном случае пропускаем два документа.
И кроме того, можно объединять все эти методы в цепочки:
1 2 3 4 5 6 | > var cursor = db.users.find() > cursor.sort({name:1}).limit(3).skip(2);null; null > cursor.forEach(function(obj){ ... print(obj.name); ... }) |
Команды группировки: count, distinct.
Число элементов в коллекции
С помощью функции count() можно получить число элементов в коллекции:
1 | > db.users.count() |
Можно группировать параметры поиска и функцию count, чтобы подсчитать, сколько определенных документов
, например, у которых name=Tom:
1 | > db.users.find({name: "Tom"}).count() |
Более того мы можем создавать цепочки функций, чтобы конкретизировать условия подсчета:
1 | > db.users.find({name: "Tom"}).skip(2).count(true) |
Здесь надо отметить, что по умолчанию функция count не используется с функциями limit и skip. Чтобы их использовать, как в примере выше, в функцию count надо передать булевое значение true
Функция distinct
В коллекции могут быть документы, которые содержат одинаковые значения для одного или нескольких полей. Например, в нескольких документах определено name: "Tom". И нам надо найти только уникальные различающиеся значения для одного из полей документа. Для этого мы можем воспользоваться функцией distinct:
1 2 | > db.users.distinct("name") ["Tom", "Bill", "Bob"] |
Здесь запрашиваются только уникальные значения для поля name. И на следующей строке консоль выводит в виде массива найденные уникальные значения.
Операторы выбора
Условные операторы
Условные операторы задают условие, которому должно соответствовать значение поля документа:
-
$eq (равно) -
$ne (не равно) -
$gt (больше чем) -
$lt (меньше чем) -
$gte (больше или равно) -
$lte (меньше или равно) -
$in определяет массив значений, одно из которых должно иметь поле документа -
$nin определяет массив значений, которые не должно иметь поле документа
Например, найдем все документы, у которых значение ключа age меньше 30:
1 | > db.users.find ({age: {$lt : 30}}) |
Аналогично будет использование других операторов сравнения. Например, тот же ключ, только больше 30:
1 | > db.users.find ({age: {$gt : 30}}) |
Обратите внимание, что сравнение здесь проводится над целочисленными типами, а не строками. Если ключ age представляет строковые значения, то соответственно надо проводить сравнение над строками: db.users.find ({age: {$gt : "30"}}), однако результат будет тем же.
Но представим ситуацию, когда нам надо найти все объкты со значением поля age больше 30, но меньше 50. В этом случае мы можем комбинировать два оператора: