В главе 1 мы вкратце рассмотрели команду find
. Однако, find
— это не только селекторы. Как уже упоминалось, результатом find
является курсор. Пришло время рассмотреть это детальнее.
Прежде чем переходить к курсорам, следует знать, что find
принимает второй необязательный параметр. Это — список полей, которые мы хотим получить. Например, мы можем получить все имена единорогов следующим запросом:
db.unicorns.find(null, {name: 1});
Поле _id
по умолчанию возвращается всегда. Мы можем явным способом исключить его, указав {name:1, _id: 0}
.
За исключением поля _id
, нельзя смешивать включения и исключения полей. Задумавшись, можно понять, зачем так сделано. Можно или хотеть включить или хотеть наоборот — исключить определённые поля явным образом.
Я уже несколько раз упомянул, что find
возвращает курсор, который исполняется отложенно — по мере необходимости. Однако, вы уже без сомнения могли видеть, что find
исполняется мгновенно. Такое поведение характерно только для консоли. Можно пронаблюдать за истинным поведением курсоров, взглянув на любой из методов, который мы можем присоединить к find
. Первым из них будет sort
. Синтаксис sort
примерно такой же, как у выбора полей, который мы видели в предыдущем разделе. Мы указываем поля, по которым надо сортировать, используя 1
для сортировки по возрастанию и -1
для сортировки по убыванию. Например:
//сортируем по весу — от тяжёлых к лёгким единорогам
db.unicorns.find().sort({weight: -1})
//по имени единорога, затем по числу убитых вампиров:
db.unicorns.find().sort({name: 1, vampires: -1})
Подобно реляционной базе данных, MongoDB может использовать индексы для сортировки. Детальнее мы рассмотрим индексы несколько позже. Однако следует знать, что без индекса MongoDB ограничивает размер сортируемых данных. Если вы попытаетесь отсортировать большой объем данных, не используя индекс, вы получите ошибку. Некоторые считают это ограничением. Хотя я думаю, что и другим базам данных не мешало бы запрещать выполнение неоптимальных запросов. (Я не стану превращать каждый недостаток MongoDB в её достоинство, однако я сталкивался с большим числом неоптимальных баз данных, которым очень не хватало подобного режима строгой проверки.)
Разбиение на страницы может быть осуществлено с помощью методов limit
и skip
. Чтобы получить второго и третьего по весу единорога, можно выполнить:
db.unicorns.find().sort({weight: -1}).limit(2).skip(1)
Используя limit
вместе с sort
можно избежать проблем с сортировкой по неиндексированным полям.
Консоль позволяет выполнить count
прямо над коллекцией:
db.unicorns.count({vampires: {$gt: 50}})
На практике же count
— это метод курсора, консоль просто обеспечивает удобное сокращение. С драйверами, не поддерживающим подобного сокращения, нужно писать что-то вроде этого (конечно, и в консоли тоже так можно):
db.unicorns.find({vampires: {$gt: 50}}).count()
Довольно просто пользоваться find
и курсорами. Есть еще несколько дополнительных команд, которые мы либо рассмотрим позже, либо не рассмотрим вообще (так как они применяются лишь в граничных случаях), но теперь, я думаю, вы должны уже освоиться в работе с консолью mongo
и пониманием основных принципов MongoDB.