介绍
在本实验中,你将学习如何使用各种查询技术有效地过滤 MongoDB 集合。本实验涵盖了应用多个条件、使用比较运算符、使用正则表达式进行匹配、检查字段是否存在以及查找 null 值。这些技能对于在 MongoDB 中进行精确的数据检索至关重要。分步说明提供了实践示例,帮助你掌握 MongoDB 查询的基础知识。
在本实验中,你将学习如何使用各种查询技术有效地过滤 MongoDB 集合。本实验涵盖了应用多个条件、使用比较运算符、使用正则表达式进行匹配、检查字段是否存在以及查找 null 值。这些技能对于在 MongoDB 中进行精确的数据检索至关重要。分步说明提供了实践示例,帮助你掌握 MongoDB 查询的基础知识。
在本步骤中,你将学习如何应用多个条件来过滤 MongoDB 集合中的文档。通过组合多个标准,可以实现更精确的查询。
首先,打开你的终端并启动 MongoDB Shell。这个交互式 shell 是你执行所有数据库命令的地方。
mongosh
进入 mongosh shell 后,你将看到一个 > 提示符。接下来,我们将切换到一个名为 school_database 的新数据库,并创建一个包含一些示例数据的 students 集合。
use school_database
db.students.insertMany([
{ name: "Alice", age: 22, grade: "A", major: "Computer Science" },
{ name: "Bob", age: 20, grade: "B", major: "Mathematics" },
{ name: "Charlie", age: 25, grade: "A", major: "Physics" },
{ name: "David", age: 19, grade: "C", major: "Computer Science" }
]);
此命令将向 students 集合插入四个文档。现在,让我们查找满足多个条件的学生。我们将使用 $and 操作符来查找年龄大于或等于 20 岁 并且 成绩为 "A" 的学生。
db.students.find({
$and: [{ age: { $gte: 20 } }, { grade: "A" }]
});
此查询使用了 $gte(大于或等于)和 $and,以确保同时满足这两个条件。输出将显示 Alice 和 Charlie:
[
{
_id: ObjectId("..."),
name: 'Alice',
age: 22,
grade: 'A',
major: 'Computer Science'
},
{
_id: ObjectId("..."),
name: 'Charlie',
age: 25,
grade: 'A',
major: 'Physics'
}
]
接下来,我们将使用 $or 操作符来查找至少满足多个条件中任一条件的文档。此查询将查找专业为 "Computer Science" 或 年龄小于 21 岁的学生。
db.students.find({
$or: [{ major: "Computer Science" }, { age: { $lt: 21 } }]
});
此查询使用了 $lt(小于)。结果将包括 Alice 和 David(计算机科学专业)以及 Bob 和 David(年龄小于 21 岁)。由于 David 同时满足两个条件,他只出现一次。
[
{
_id: ObjectId("..."),
name: 'Alice',
age: 22,
grade: 'A',
major: 'Computer Science'
},
{
_id: ObjectId("..."),
name: 'Bob',
age: 20,
grade: 'B',
major: 'Mathematics'
},
{
_id: ObjectId("..."),
name: 'David',
age: 19,
grade: 'C',
major: 'Computer Science'
}
]
在下一步中,你将探索更多的比较操作符。现在,你可以继续留在 mongosh shell 中。
在本步骤中,你将使用 MongoDB 的比较操作符来构建更复杂的查询。这些操作符允许你根据值比较来过滤数据。
你应该仍然处于上一步的 mongosh shell 中。首先,让我们清空现有集合并插入带有 credits 字段的新数据以供使用。
db.students.drop();
db.students.insertMany([
{
name: "Alice",
age: 22,
grade: "A",
major: "Computer Science",
credits: 45
},
{ name: "Bob", age: 20, grade: "B", major: "Mathematics", credits: 35 },
{ name: "Charlie", age: 25, grade: "A", major: "Physics", credits: 50 },
{ name: "David", age: 19, grade: "C", major: "Computer Science", credits: 25 }
]);
现在,让我们使用 "大于" ($gt) 和 "小于" ($lt) 操作符来查找年龄大于 20 岁但小于 25 岁的学生。
db.students.find({ age: { $gt: 20, $lt: 25 } });
此查询将只返回 Alice 的文档,因为她 22 岁。
接下来,使用 "大于或等于" ($gte) 和 "小于或等于" ($lte) 来查找 credits 在 40 到 50 之间(包含边界)的学生。
db.students.find({ credits: { $gte: 40, $lte: 50 } });
此查询将返回 Alice(45 credits)和 Charlie(50 credits)。
最后,让我们使用 "不等于" ($ne) 操作符来查找所有 grade 不是 "C" 的学生。
db.students.find({ grade: { $ne: "C" } });
这将返回 Alice、Bob 和 Charlie,排除 grade 为 "C" 的 David。这些操作符是创建详细且特定查询的基础。
正则表达式(regex)提供了一种灵活的方式来执行强大的文本搜索。在本步骤中,你将学习如何在 MongoDB 查询中使用正则表达式。
首先,让我们为本步骤准备数据。清空集合并插入包含更多详细字符串字段的新文档。
db.students.drop();
db.students.insertMany([
{
name: "Alice Johnson",
age: 22,
major: "Computer Science",
email: "alice.j@example.com"
},
{
name: "Bob Smith",
age: 20,
major: "Mathematics",
email: "bob.smith@university.edu"
},
{
name: "Charlie Brown",
age: 25,
major: "Physics",
email: "charlie.brown@school.org"
},
{
name: "David Lee",
age: 19,
major: "Computer Engineering",
email: "david.lee@tech.net"
}
]);
要查找所有名字以 "Alice" 开头的学生,你可以使用带有 ^ 锚点的 $regex 操作符。
db.students.find({ name: { $regex: "^Alice" } });
此查询将返回 "Alice Johnson" 的文档。^ 字符表示字符串的开头。
要查找来自特定域(如 example.com)的电子邮件地址的学生,请使用 $ 锚点匹配字符串的结尾。
db.students.find({ email: { $regex: "@example.com$" } });
这将找到 "Alice Johnson",因为她的电子邮件以 @example.com 结尾。
你还可以执行不区分大小写的搜索。以下查询通过使用 i 选项,查找名字中包含 "smith" 的任何学生,而不考虑大小写。
db.students.find({ name: { $regex: "smith", $options: "i" } });
此查询将匹配 "Bob Smith"。
最后,要查找包含 "Computer" 一词的任何专业,你可以使用简单的正则表达式模式,而无需任何锚点。
db.students.find({ major: { $regex: "Computer" } });
这将返回 "Alice Johnson"(Computer Science)和 "David Lee"(Computer Engineering)。
有时,集合中的文档结构不同。本步骤将教你如何根据特定字段是否存在来查询文档。
让我们开始插入一组新文档,其中一些字段缺失。
db.students.drop();
db.students.insertMany([
{ name: "Alice", age: 22, major: "Computer Science", scholarship: 1000 },
{ name: "Bob", age: 20, major: "Mathematics" },
{ name: "Charlie", age: 25, major: "Physics", internship: "Research Lab" },
{ name: "David", age: 19, contact: { phone: "555-1234" } }
]);
要查找所有具有 scholarship 字段的学生,请使用值为 true 的 $exists 操作符。
db.students.find({ scholarship: { $exists: true } });
此查询将只返回 Alice 的文档,因为她是唯一拥有 scholarship 字段的学生。
相反,要查找没有 internship 字段的学生,请将 $exists 设置为 false。
db.students.find({ internship: { $exists: false } });
这将返回 Alice、Bob 和 David 的文档,因为他们都没有 internship 字段。
$exists 操作符也适用于嵌套字段。要查找拥有包含 phone 字段的 contact 对象的学生,你可以使用点表示法(dot notation)。
db.students.find({ "contact.phone": { $exists: true } });
此查询专门查找 contact 对象内的 phone 字段,并将返回 David 的文档。
在本步骤的最后,你将学习如何查询包含 null 值的文档。null 值代表有意缺失一个值。
首先,我们来设置一个包含 null 值和缺失字段的文档集合。
db.students.drop();
db.students.insertMany([
{ name: "Alice", age: 22, email: null },
{ name: "Bob", age: 20, major: "Mathematics" },
{ name: "Charlie", age: null, major: "Physics" },
{ name: "David", contact: { email: null } }
]);
要查找字段具有 null 值的文档,你可以直接查询 null。以下查询会查找 email 字段为 null 或 email 字段不存在的所有文档。
db.students.find({ email: null });
此查询将返回所有四个文档:Alice(email 显式为 null),Bob(email 字段缺失),Charlie(email 字段缺失),以及 David(email 字段缺失)。
要仅查找字段显式设置为 null 的文档,你必须将 null 检查与 $exists 检查结合起来。
db.students.find({ email: { $type: "null" } });
或者,你也可以使用 $type 操作符。null 的 BSON 类型是 10。此查询将仅返回 Alice 的文档。
db.students.find({ email: { $type: 10 } });
你也可以查询嵌套文档中的 null 值。以下查询会查找 contact 对象中 email 字段为 null 或 contact 字段不存在的文档。
db.students.find({ "contact.email": null });
这将返回所有四个文档:Alice、Bob 和 Charlie(contact 字段缺失),以及 David(contact.email 显式为 null)。理解如何查询 null 对于处理不完整或稀疏的数据至关重要。
完成后,你可以通过输入 exit 或按 Ctrl+D 来退出 mongosh shell。
在本实验中,你学习了 MongoDB 中过滤集合的几种基本技术。你练习了使用 $and 和 $or 操作符应用多个条件,这使得创建复杂且精确的查询成为可能。你还探索了一系列比较操作符,如 $gt、$lt 和 $ne,用于优化搜索条件。此外,你还获得了使用正则表达式匹配文本、使用 $exists 检查字段是否存在以及查询 null 值的经验。这些技能为你有效地检索和操作 MongoDB 数据奠定了坚实的基础。