MongoDB - 查询文档
MongoDB - 查询文档
Section titled “MongoDB - 查询文档”查询是从数据库中检索数据的过程。MongoDB 提供丰富而强大的查询语言,可帮助您找到所需的精确文档。本章涵盖查询的基础知识,从基本查找操作到复杂的逻辑条件。
设置:创建示例数据
Section titled “设置:创建示例数据”我们首先向 posts 集合插入一个真实的数据集。我们将使用 insertMany 等现代方法和适当的数据类型(如 Number、Boolean、Array 等)。
db.posts.insertMany([ { title: "Introduction to MongoDB", author: "Chris", tags: ["mongodb", "database", "nosql"], views: 1500, isPublished: true, comments: [ { user: "Alice", text: "Great overview!" }, { user: "Bob", text: "Very helpful, thanks." } ] }, { title: "Advanced Aggregation", author: "Sarah", tags: ["mongodb", "aggregation", "advanced"], views: 750, isPublished: true }, { title: "Schema Design Best Practices", author: "Chris", tags: ["mongodb", "schema", "modeling"], views: 2200, isPublished: true }, { title: "Upcoming Features", author: "Chris", tags: ["mongodb", "future"], views: 50, isPublished: false }]);基本查询:find() 和 findOne()
Section titled “基本查询:find() 和 findOne()”find(query, projection) 是主要的查询方法。它返回一个游标(cursor),该游标是指向结果集的指针。findOne(query, projection) 是一种便捷的替代方法,它只返回与查询匹配的第一个文档,如果没有找到匹配项,则返回 null。
// 查找集合中的所有文档(空查询文档)> db.posts.find({})
// 查找 'Chris' 撰写的第一个文档> db.posts.findOne({ author: "Chris" })
// 注意:mongosh 会自动格式化 JSON 输出以提高可读性。// 传统的 .pretty() 方法仍然有效,但已不再必需。使用查询操作符进行筛选
Section titled “使用查询操作符进行筛选”要创建更具体的查询,您可以使用查询操作符。它们相当于 SQL 中的 WHERE 子句。
| 操作 | 语法 | 示例(在 posts 集合上) | 关系型数据库(RDBMS)等效 |
|---|---|---|---|
| 相等 | { | db.posts.find({ author: “Sarah” }) | WHERE author = ‘Sarah’ |
| 小于 | { | db.posts.find({ views: { $lt: 1000 } }) | WHERE views < 1000 |
| 大于或等于 | { | db.posts.find({ views: { $gte: 1500 } }) | WHERE views >= 1500 |
| 不等于 | { | db.posts.find({ author: { $ne: “Chris” } }) | WHERE author != ‘Chris’ |
| 值在数组中 | { | db.posts.find({ author: { $in: [“Chris”, “Sarah”] } }) | WHERE author IN (‘Chris’, ‘Sarah’) |
| 值不在数组中 | { | db.posts.find({ tags: { $nin: [“future”, “draft”] } }) | WHERE tag is not in (‘future’, ‘draft’) |
组合条件:逻辑操作符
Section titled “组合条件:逻辑操作符”隐式 AND
Section titled “隐式 AND”默认情况下,当您在查询文档中提供多个字段时,MongoDB 会执行逻辑 AND 操作。以下查询会查找由 ‘Chris’ 撰写且已发布的文章。
> db.posts.find({ author: "Chris", isPublished: true })使用 $or 进行 OR 逻辑查询
Section titled “使用 $or 进行 OR 逻辑查询”要查找匹配多个条件中至少一个的文档,请使用 $or 操作符,它接受一个查询文档数组。
// 查找浏览量小于 100 或尚未发布的文章> db.posts.find({ $or: [ { views: { $lt: 100 } }, { isPublished: false } ]})使用 $nor 进行 NOR 逻辑查询
Section titled “使用 $nor 进行 NOR 逻辑查询”$nor 操作符查找不匹配数组中所有条件的文档。它的意思是“既不满足这个,也不满足那个”。
// 查找作者不是 'Sarah' 且不包含 'nosql' 标签的文章> db.posts.find({ $nor: [ { author: 'Sarah' }, { tags: 'nosql' } ]})查询数组和嵌入式文档
Section titled “查询数组和嵌入式文档”匹配数组元素
Section titled “匹配数组元素”要查找数组包含特定元素的文档,只需查询该值即可。
// 查找所有带有 'mongodb' 标签的文章> db.posts.find({ tags: "mongodb" })使用点表示法查询嵌入式文档
Section titled “使用点表示法查询嵌入式文档”使用点表示法(dot notation)查询嵌入式文档或文档数组中的字段。
// 查找用户 'Alice' 发表过评论的文章> db.posts.find({ "comments.user": "Alice" })使用 $elemMatch 进行精确匹配
Section titled “使用 $elemMatch 进行精确匹配”一个简单的查询,例如 { 'comments.user': 'Alice', 'comments.text': '...' },可能会匹配到如果一个评论是 Alice 写的,而另一个评论包含指定的文本。为了确保数组中的单个元素满足多个条件,请使用 $elemMatch。
// 查找包含 'Bob' 评论中带有“helpful”一词的文章// 这确保了 'user' 和 'text' 条件应用于同一个评论对象> db.posts.find({ comments: { $elemMatch: { user: "Bob", text: /helpful/ } }})实际应用:Node.js 驱动示例
Section titled “实际应用:Node.js 驱动示例”以下是在典型 Node.js 应用程序中使用官方 mongodb 驱动程序执行查询的方式。首先,请确保您已安装该驱动程序:npm install mongodb。
const { MongoClient } = require('mongodb');
// 替换为您的 MongoDB 部署的连接字符串。const uri = 'mongodb://localhost:27017';const client = new MongoClient(uri);
async function run() { try { await client.connect(); const database = client.db('yourDbName'); // 替换为您的数据库名称 const posts = database.collection('posts');
// 查询 Chris 撰写的热门已发布文章 const query = { author: 'Chris', isPublished: true, views: { $gte: 1000 } };
const cursor = posts.find(query);
// 如果未找到文档,则打印消息 if ((await posts.countDocuments(query)) === 0) { console.log("No documents found!"); }
// 打印每个文档 for await (const doc of cursor) { console.dir(doc); }
} finally { // 确保当您完成/出错时客户端会关闭 await client.close(); }}run().catch(console.dir);调试与性能分析
Section titled “调试与性能分析”要了解 MongoDB 如何执行您的查询以及识别性能瓶颈,请使用 explain() 方法。这对于检查您的查询是否有效利用索引至关重要。
> db.posts.find({ author: 'Chris', views: { $gt: 1000 } }).explain('executionStats')
// 分析输出中的 'executionStats'。// 'winningPlan' 中显示 'IXSCAN'(索引扫描)远优于 'COLLSCAN'(集合扫描)。