Сортировка и ограничение результатов MongoDB

MongoDBBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе вы изучите основные методы запросов MongoDB для сортировки, ограничения и фильтрации результатов базы данных. Эти навыки необходимы для эффективного управления и извлечения данных. Вы будете использовать оболочку MongoDB (mongosh) для выполнения этих операций над образцом коллекции документов.

Лабораторная работа проведет вас через сортировку документов по одному или нескольким полям, контроль количества возвращаемых результатов с использованием ограничений (limits) и смещений (offsets), а также подсчет документов, соответствующих определенным критериям. К концу этой лабораторной работы вы получите твердое понимание того, как организовывать и извлекать данные из базы данных MongoDB.

Сортировка документов по одному полю

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

Сначала откройте оболочку MongoDB для взаимодействия с базой данных. В терминале выполните следующую команду:

mongosh

Находясь в оболочке, переключитесь на базу данных bookstore.

use bookstore

Чтобы увидеть документы в коллекции books, вы можете использовать метод find().

db.books.find();

Теперь давайте отсортируем эти документы. Чтобы отсортировать по одному полю, вы добавляете метод .sort() к запросу find(). Метод sort() принимает объект, указывающий поле для сортировки и направление: 1 для возрастания и -1 для убывания.

Отсортируем книги по количеству страниц в порядке возрастания (от наименьшего к наибольшему количеству страниц).

db.books.find().sort({ pages: 1 });

Вы увидите книгу с наименьшим количеством страниц, "Python Basics", перечисленную первой.

[
  {
    _id: ObjectId('...'),
    title: 'Python Basics',
    pages: 250,
    price: 29.99
  },
  {
    _id: ObjectId('...'),
    title: 'MongoDB Fundamentals',
    pages: 300,
    price: 34.99
  },
  ...
]

Далее отсортируем книги по цене в порядке убывания, чтобы сначала увидеть самые дорогие.

db.books.find().sort({ price: -1 });

Эта команда отобразит "Data Science" вверху, так как у нее самая высокая цена.

[
  {
    _id: ObjectId('...'),
    title: 'Data Science',
    pages: 350,
    price: 44.99
  },
  {
    _id: ObjectId('...'),
    title: 'JavaScript Advanced',
    pages: 400,
    price: 39.99
  },
  ...
]

Сортировка по нескольким полям

Иногда сортировки по одному полю недостаточно. MongoDB позволяет указывать несколько ключей для сортировки, чтобы создавать более точные порядки. На этом шаге вы научитесь сортировать документы на основе последовательности полей.

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

db.books.insertMany([
  { title: "Machine Learning", pages: 420, price: 39.99 },
  { title: "Web Development", pages: 380, price: 39.99 }
]);

Теперь у нас есть три книги по цене $39.99. Если мы будем сортировать только по цене, порядок этих трех книг не гарантируется. Чтобы создать предсказуемый порядок, мы можем добавить второй ключ сортировки.

Отсортируем книги сначала по price в порядке возрастания, а затем по pages в порядке убывания для книг с одинаковой ценой.

db.books.find().sort({ price: 1, pages: -1 });

Процессор запросов сначала сортирует все документы по price. Затем для документов с одинаковой price (как у наших трех книг по $39.99) он сортирует их по pages в порядке убывания.

Ваш вывод для книг по $39.99 должен выглядеть в следующем порядке:

  1. "Machine Learning" (420 страниц)
  2. "JavaScript Advanced" (400 страниц)
  3. "Web Development" (380 страниц)
[
  ...,
  {
    _id: ObjectId('...'),
    title: 'Machine Learning',
    pages: 420,
    price: 39.99
  },
  {
    _id: ObjectId('...'),
    title: 'JavaScript Advanced',
    pages: 400,
    price: 39.99
  },
  {
    _id: ObjectId('...'),
    title: 'Web Development',
    pages: 380,
    price: 39.99
  },
  ...
]

Этот метод полезен для создания сложных, стабильных сортировок для пользовательских интерфейсов и отчетов.

Ограничение и пропуск результатов

При работе с большими наборами данных часто требуется получить только подмножество результатов. MongoDB предоставляет для этой цели методы .limit() и .skip(). Вместе они являются основой для реализации постраничного вывода.

Метод .limit() ограничивает количество документов, возвращаемых запросом. Давайте получим только 3 самые дорогие книги.

db.books.find().sort({ price: -1 }).limit(3);

Эта команда сначала сортирует все книги по цене в порядке убывания, а затем возвращает только первые три документа из отсортированного списка.

Метод .skip() указывает курсору пропустить указанное количество документов в начале набора результатов. Это полезно для навигации по страницам данных.

Например, чтобы получить вторую страницу результатов, где на каждой странице по 2 книги, вам нужно пропустить первые 2 книги и ограничить результат 2. Применим это к нашему списку, отсортированному по цене, чтобы получить 3-ю и 4-ю самые дорогие книги.

db.books.find().sort({ price: -1 }).skip(2).limit(2);

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

  1. sort({ price: -1 }): Сортирует все книги от самых дорогих к самым дешевым.
  2. skip(2): Пропускает 2 самые дорогие книги.
  3. limit(2): Возвращает следующие 2 книги из списка.

Вывод покажет третью и четвертую книги в отсортированном списке.

[
  {
    _id: ObjectId('...'),
    title: 'JavaScript Advanced',
    pages: 400,
    price: 39.99
  },
  {
    _id: ObjectId('...'),
    title: 'Web Development',
    pages: 380,
    price: 39.99
  }
]

Регулируя значения в skip() и limit(), вы можете реализовать полноценную систему постраничного вывода.

Подсчет документов

Другим распространенным требованием является подсчет количества документов в коллекции, либо общего количества, либо соответствующих определенному фильтру. MongoDB предоставляет для этого метод countDocuments().

Чтобы получить общее количество книг в нашей коллекции, выполните следующую команду:

db.books.countDocuments();

Это вернет общее количество документов, которое должно быть 6 после добавлений из Шага 2.

Более мощным является то, что countDocuments() может принимать фильтр запроса для подсчета только тех документов, которые соответствуют определенным критериям. Давайте посчитаем, сколько книг стоят дороже 35 долларов. Для этого мы используем оператор запроса $gt (больше чем).

db.books.countDocuments({ price: { $gt: 35 } });

Это вернет количество книг, цена которых больше 35.

Вы также можете использовать несколько условий в вашем фильтре. Давайте посчитаем книги, цена которых составляет ровно $39.99, а количество страниц — 400 или более. Здесь мы используем оператор $gte (больше или равно).

db.books.countDocuments({ price: 39.99, pages: { $gte: 400 } });

Эта команда вернет 2, что соответствует "Machine Learning" (420 страниц) и "JavaScript Advanced" (400 страниц). Использование countDocuments() с фильтрами — это эффективный способ получения статистики о ваших данных без извлечения самих документов.

Чтобы выйти из оболочки MongoDB, вы можете набрать exit или нажать Ctrl+D.

exit;

Резюме

В этой лабораторной работе вы изучили несколько основных методов запросов MongoDB. Вы начали с сортировки документов по одному полю как в порядке возрастания, так и в порядке убывания с помощью метода .sort(). Затем вы перешли к многоключевой сортировке, которая обеспечивает более сложную и стабильную сортировку результатов.

Далее вы узнали, как контролировать размер набора результатов с помощью .limit() для ограничения количества возвращаемых документов и .skip() для реализации постраничного вывода. Наконец, вы научились использовать countDocuments() для эффективного подсчета документов как во всей коллекции, так и соответствующих определенным критериям фильтрации. Эти команды являются фундаментальными инструментами для любого разработчика, работающего с MongoDB.