排序和限制 MongoDB 结果

MongoDBBeginner
立即练习

介绍

在本实验中,你将学习 MongoDB 查询的基本技术,包括对数据库结果进行排序、限制和过滤。这些技能对于高效地管理和检索数据至关重要。你将使用 MongoDB shell (mongosh) 对文档的示例集合执行这些操作。

本实验将指导你按单个或多个字段对文档进行排序,使用 limit 和 offset 控制返回结果的数量,以及计算符合特定条件的文档数量。完成本实验后,你将对如何组织和从 MongoDB 数据库中检索数据有扎实的理解。

这是一个实验(Guided Lab),提供逐步指导来帮助你学习和实践。请仔细按照说明完成每个步骤,获得实际操作经验。根据历史数据,这是一个 初级 级别的实验,完成率为 95%。获得了学习者 100% 的好评率。

按单个字段对文档进行排序

在本步骤中,你将学习如何在 MongoDB 集合中对文档进行排序。排序允许你以特定顺序组织查询结果,这对于数据分析和展示至关重要。你的环境已预先配置了包含 books 集合的 bookstore 数据库。

首先,打开 MongoDB shell 以与数据库进行交互。在你的终端中,运行以下命令:

mongosh

进入 shell 后,切换到 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();

这将返回文档总数,在添加了第 2 步中的内容后,该数量应为 6

更强大的是,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 shell,你可以输入 exit 或按 Ctrl+D

exit;

总结

在本实验中,你学习了几个基本的 MongoDB 查询技术。你首先使用 .sort() 方法按升序和降序对单个字段的文档进行排序。然后,你进阶到多键排序,这允许更复杂和稳定的结果排序。

接下来,你探索了如何使用 .limit() 限制返回的文档数量以及使用 .skip() 实现分页来控制结果集的大小。最后,你学习了如何使用 countDocuments() 高效地计算文档数量,包括整个集合的文档数量以及匹配特定过滤条件的文档数量。这些命令是任何使用 MongoDB 的开发者的基本工具。