Docs 菜单
Docs 主页
/ / /
Node.js 驱动程序
/ / /

Retrieve Data

在此页面上

  • Overview
  • 查找文档
  • 汇总文档中的数据
  • 监控数据变化

您可以执行查找操作,以便从 MongoDB 数据库检索数据。您可以通过调用 find()findOne() 方法来执行查找操作,以便根据一组条件来匹配文档。

提示

互动实验室

本页包括一个简短的交互式实验,演示如何使用 find() 方法检索数据。您无需安装 MongoDB 或代码编辑器,即可直接在浏览器窗口中完成此实验。

若要启动实验室,请单击页面顶部的“Open Interactive Tutorial”按钮。要将实验室扩展为全屏格式,请单击实验室窗格右上角的全屏按钮 ()。

您还可以通过指定可选参数或链接其他方法,进一步指定查找操作返回的信息,如以下指南所示:

  • 对结果进行排序

  • 跳过返回的结果

  • 限制返回结果的数量

  • 指定要返回的字段

还可以使用聚合操作来检索数据。这种操作类型让您可以对匹配的数据应用一套有序的转换管道。

如果要监测有无符合特定条件的数据传入数据库,则可以使用监控(watch)操作。这样,当有匹配的数据插入时,您可实时收到通知。

注意

您的查询操作可能会返回对包含匹配文档的游标的引用。要了解如何检查存储在游标中的数据,请参阅游标基础知识页面

您可以使用 Node.js 驱动程序进行连接并对以下环境中托管的部署执行读取操作:

  • MongoDB Atlas :用于在云中部署 MongoDB 的完全托管服务

  • MongoDB Enterprise:基于订阅、自行管理的 MongoDB 版本

  • MongoDB Community:source-available、免费使用且可自行管理的 MongoDB 版本

要了解有关在 Atlas 用户界面中为 MongoDB Atlas 托管的部署执行读取操作的更多信息,请参阅查看、筛选和排序文档

您可对 Collection 对象调用 find() 方法。此方法接受用于描述待检索文档的查询文档。有关如何指定查询文档的更多信息,请参阅指定查询指南。

提示

无查询条件

要执行没有查询条件的查找操作,您可以在查找方法参数中传递空查询或省略查询文档。

以下操作均返回 myColl 集合中的所有文档:

myColl.find(); // no query
myColl.find({}); // empty query

如果不传递查询或向 findOne() 方法传递空查询,则该操作将从集合中返回单个文档。

即使在传递空查询时,您也可以在查找操作中指定选项。例如,以下代码演示了如何在执行一个查询参数为空的查找操作时,指定一个投影作为选项:

const options = {
projection: { _id: 0, field1: 1 },
};
const findResult = await myColl.findOne({}, options);

有关投影文档字段的更多信息,请参阅指定要返回的字段指南。

find()方法会返回一个Cursor 实例,您可以从该实例访问匹配的文档。findOne()方法会返回一个Promise 实例,您可以解析该实例以访问匹配的文档;或者,如果没有匹配项,该实例则会返回null 值。

例子

一家披萨餐厅想查找 Lemony Snicket 昨天订购的所有披萨。他们在 orders 集合上运行以下 find() 查询:

// Search for orders by name and within a specific date range
const findResult = orders.find({
name: "Lemony Snicket",
date: {
$gte: new Date(new Date().setHours(00, 00, 00)),
$lt: new Date(new Date().setHours(23, 59, 59)),
},
});

操作返回后,findResult 变量将引用 Cursor。 您可以打印使用 for await...of 语法检索到的文档,如下所示:

for await (const doc of findResult) {
console.log(doc);
}

输出可能如下所示:

[
{ name: "Lemony Snicket", type: "horseradish pizza", qty: 1, status: "delivered", date: ... },
{ name: "Lemony Snicket", type: "coal-fired oven pizza", qty: 3, status: "canceled", date: ...},
...
]

有关查找操作的可运行演示代码,请参阅以下使用示例:

有关 findOne()find() 方法的更多信息,请参阅以下服务器手册文档:

如果要运行自定义处理管道以从数据库中获取数据,可以使用 aggregate() 方法。此方法接受依序运行的聚合表达式。通过这些表达式,可以对集合中的结果数据进行筛选、分组和排列。

例子

一家披萨餐厅想按需运行状态报告来总结过去一周的披萨订单。为此,它们会对 orders 集合运行以下 aggregate() 查询,从而获取每个不同“状态”字段的总和:

// Group orders by status within the last week
const aggregateResult = orders.aggregate([
{
$match: {
date: {
$gte: new Date(new Date().getTime() - 1000 * 3600 * 24 * 7),
$lt: new Date(),
},
},
},
{
$group: {
_id: "$status",
count: {
$sum: 1,
},
},
},
]);

操作返回后,aggregateResult 变量将引用 Cursor。 您可以打印使用 for await...of 语法检索到的文档,如下所示:

for await (const doc of aggregateResult) {
console.log(doc);
}

输出可能如下所示:

[
{ _id: 'delivering', count: 5 },
{ _id: 'delivered', count: 37 },
{ _id: 'created', count: 9 }
]

有关如何构建聚合管道的更多信息,请参阅服务器手册中的聚合指南或聚合操作

您可以使用watch()方法来监视集合,以了解对符合特定条件的集合所做的更改。这些更改包括插入、更新、替换和删除的文档。 您可以向此方法传递一个聚合命令管道,每当对集合执行写入操作时,该管道都会对更改的数据按顺序运行。

例子

一家披萨餐厅希望在收到新的披萨订单时获得通知。为了实现这一目标,他们创建了一个聚合管道来过滤插入操作并返回特定字段。他们将此管道传递给在 orders 集合上调用的watch() 方法,如下所示:

// Set up a change stream to listen for new order insertions
const changeStream = orders.watch([
{ $match: { operationType: "insert" } },
{
$project: {
"fullDocument.name": 1,
"fullDocument.address": 1,
},
},
]);
changeStream.on("change", change => {
const { name, address } = change.fullDocument;
console.log(`New order for ${name} at ${address}.`);
});

有关 watch() 方法的可运行示例,请参阅监视变更使用示例。

后退

读取操作