介绍
在本实验中,你将学习 MongoDB 的核心查询技术。你将从连接数据库和插入数据开始。然后,你将练习检索文档,使用精确匹配和比较运算符进行过滤,选择要返回的特定字段,并通过排序和限制结果来格式化输出。完成本实验后,你将为在 MongoDB 数据库中查询数据打下坚实的基础。
在本实验中,你将学习 MongoDB 的核心查询技术。你将从连接数据库和插入数据开始。然后,你将练习检索文档,使用精确匹配和比较运算符进行过滤,选择要返回的特定字段,并通过排序和限制结果来格式化输出。完成本实验后,你将为在 MongoDB 数据库中查询数据打下坚实的基础。
在第一步中,你将连接到 MongoDB 服务器,创建一个数据库和一个集合,插入一些示例数据,然后从该集合中检索所有文档。这是任何数据库交互的起点。
首先,打开你的终端并运行 mongosh 命令来启动 MongoDB Shell。
mongosh
你的终端提示符将发生变化,表明你现在已进入 MongoDB Shell,可以执行数据库命令了。
接下来,切换到一个名为 bookstore 的新数据库。如果数据库不存在,MongoDB 会在你首次存储数据时创建它。
use bookstore
现在,让我们向一个名为 books 的新集合中插入一些文档。集合是 MongoDB 文档的集合,类似于关系数据库中的表。insertMany() 方法允许你一次添加多个文档。
db.books.insertMany([
{ title: "Python Basics", author: "John Smith", year: 2022, stock: 15 },
{ title: "MongoDB Essentials", author: "Jane Doe", year: 2023, stock: 8 },
{ title: "Web Development", author: "Alice Johnson", year: 2021, stock: 20 }
]);
执行命令后,你将看到一个确认消息,表明文档已成功插入。
要检索并查看 books 集合中的所有文档,请使用不带任何参数的 find() 方法。
db.books.find();
输出将列出你刚刚插入的所有三个文档。每个文档都有一个 _id 字段,这是 MongoDB 自动添加的唯一标识符。
[
{
_id: ObjectId("..."),
title: 'Python Basics',
author: 'John Smith',
year: 2022,
stock: 15
},
{
_id: ObjectId("..."),
title: 'MongoDB Essentials',
author: 'Jane Doe',
year: 2023,
stock: 8
},
{
_id: ObjectId("..."),
title: 'Web Development',
author: 'Alice Johnson',
year: 2021,
stock: 20
}
]
现在你已经能够检索所有文档了,下一步是过滤它们以找到特定的文档。你可以通过向 find() 方法提供一个查询过滤器文档来实现这一点。这允许你对字段值执行精确匹配。
让我们查找标题完全是 "Python Basics" 的书籍。查询过滤器 { title: "Python Basics" } 告诉 MongoDB 只返回 title 字段精确匹配 "Python Basics" 的文档。
db.books.find({ title: "Python Basics" });
该命令将只返回一个符合条件的文档:
[
{
_id: ObjectId("..."),
title: 'Python Basics',
author: 'John Smith',
year: 2022,
stock: 15
}
]
你也可以基于其他字段进行查询,例如数字。例如,查找所有在 2021 年出版的书籍:
db.books.find({ year: 2021 });
要创建更精确的查询,你可以在过滤器文档中指定多个字段。这会创建一个隐式的 "AND" 条件,意味着文档必须满足所有指定的条件才能被返回。让我们查找由 "Jane Doe" 撰写且出版于 2023 年的书籍。
db.books.find({ author: "Jane Doe", year: 2023 });
此查询将返回 "MongoDB Essentials" 这本书,因为它是唯一同时匹配作者和年份的书籍。
精确匹配很有用,但通常你需要根据比较来查找文档,例如查找所有在特定年份之后出版的书籍,或者库存高于某个水平的书籍。MongoDB 为此目的提供了一组查询运算符。
比较运算符在查询文档中使用 { field: { $operator: value } } 这样的语法来指定。
让我们查找所有在 2021 年之后出版的书籍。我们将使用 "大于" 运算符 $gt。
db.books.find({ year: { $gt: 2021 } });
这将返回 "Python Basics" (2022) 和 "MongoDB Essentials" (2023)。
以下是一些其他常用的比较运算符:
$lt: 小于$gte: 大于或等于$lte: 小于或等于$ne: 不等于例如,要查找库存为 15 或更少的书籍,你可以使用 $lte 运算符。
db.books.find({ stock: { $lte: 15 } });
另一个有用的运算符是 $in,它匹配数组中指定的任何值。让我们查找所有由 "John Smith" 或 "Alice Johnson" 撰写的书籍。
db.books.find({ author: { $in: ["John Smith", "Alice Johnson"] } });
此查询将返回 "Python Basics" 和 "Web Development"。你可以将运算符与精确匹配结合起来构建更复杂的查询。例如,查找在 2022 年或之后出版且库存少于 20 的书籍。
db.books.find({ year: { $gte: 2022 }, stock: { $lt: 20 } });
默认情况下,MongoDB 查询会返回匹配文档中的所有字段。为了提高性能并使输出更清晰,你可以指定要返回的字段。这称为 projection(投影)。
Projection 由 find() 方法的第二个参数处理。此参数是一个文档,你可以在其中使用 1 指定要包含的字段,或使用 0 指定要排除的字段。
让我们检索所有书籍,但只返回它们的 title 和 author 字段。第一个参数 {} 是一个空过滤器,它匹配所有文档。
db.books.find({}, { title: 1, author: 1 });
你会注意到 _id 字段仍然包含在输出中。_id 字段默认始终返回。要排除它,你必须显式将其设置为 0。
db.books.find({}, { title: 1, author: 1, _id: 0 });
现在输出将更加简洁,只包含请求的字段:
[
{ "title": "Python Basics", "author": "John Smith" },
{ "title": "MongoDB Essentials", "author": "Jane Doe" },
{ "title": "Web Development", "author": "Alice Johnson" }
]
你可以将查询过滤器与 projection 结合使用。例如,让我们查找 2023 年出版的书籍,并只返回它们的标题。
db.books.find({ year: 2023 }, { title: 1, _id: 0 });
这个强大的功能允许你将查询结果定制为你应用程序所需的精确内容,从而减少不必要的数据传输。
通常,你需要控制查询返回结果的顺序和数量。MongoDB 提供了 cursor 方法,你可以将它们链式调用到 find() 查询上,以对结果集中的文档进行排序、跳过和限制。
要对结果进行排序,请使用 .sort() 方法。它接受一个文档,指定排序字段和方向:1 表示升序,-1 表示降序。让我们按年份降序(最新优先)对书籍进行排序。
db.books.find().sort({ year: -1 });
要限制返回的文档数量,请使用 .limit() 方法。例如,要仅获取最新的 2 本书:
db.books.find().sort({ year: -1 }).limit(2);
.skip() 方法用于跳过结果集开头指定数量的文档。这对于实现分页非常有用。让我们检索所有书籍,但跳过第一本。
db.books.find().sort({ year: 1 }).skip(1);
你可以将这些方法链接在一起,以创建强大而精确的查询。例如,要查找集合中的第二本最旧的书籍,你可以按年份升序排序,跳过第一个结果,并将输出限制为一条。
db.books.find().sort({ year: 1 }).skip(1).limit(1);
此命令将返回 "Python Basics" 这本书,该书于 2022 年出版。
最后,要退出 MongoDB shell,请键入 exit 或按 Ctrl+D。
exit;
在本实验中,你学习了编写 MongoDB 基本查询的基础知识。你首先使用 mongosh shell 连接到数据库并将文档插入集合。然后,你练习了使用 find() 检索文档,使用精确匹配和比较运算符(如 $gt 和 $in)过滤结果,并使用 projection 选择特定字段。最后,你学习了如何通过链式调用 cursor 方法(如 .sort()、.limit() 和 .skip())来格式化输出,以控制结果集的顺序和大小。这些技能构成了与 MongoDB 中的数据进行交互和管理的基础。