Access Data From a Cursor从游标访问数据
On this page本页内容
Overview概述
Read operations that return multiple documents do not immediately return all values matching the query. 返回多个文档的读取操作不会立即返回与查询匹配的所有值。Because a query can potentially match very large sets of documents, these operations rely upon an object called a cursor. 因为查询可能匹配非常大的文档集,所以这些操作依赖于一个称为游标的对象。A cursor fetches documents in batches to reduce both memory consumption and network bandwidth usage. 游标批量获取文档,以减少内存消耗和网络带宽使用。Cursors are highly configurable and offer multiple interaction paradigms for different use cases.游标是高度可配置的,并为不同的用例提供多种交互范例。
The following functions directly return cursors:以下函数直接返回游标:
Collection.find()
Collection.aggregate()
Collection.listIndexes()
Collection.listSearchIndexes()
Db.aggregate()
Db.listCollections()
Other methods such as Collection.findOne() and Collection.watch() use cursors internally, and return the results of the operations instead of a cursor.其他方法,如Collection.findOne()
和Collection.watch()
,在内部使用游标,并返回操作结果而不是游标。
Cursor Paradigms游标范式
You can work with cursors using a number of cursor paradigms. 您可以使用多种游标范例来处理游标。Most cursor paradigms allow you to access query results one document at a time, abstracting away network and caching logic. 大多数游标范式允许您一次访问一个文档的查询结果,从而抽象出网络和缓存逻辑。However, since use cases differ, other paradigms offer different access patterns, like pulling all matching documents into a collection in process memory.然而,由于用例不同,其他范式提供了不同的访问模式,比如将所有匹配的文档拉入进程内存中的集合。
Do not combine different cursor paradigms on a single cursor. 不要在一个游标上组合不同的游标范例。Operations such as 诸如hasNext()
and toArray()
each predictably modify the original cursor. hasNext()
和toArray()
之类的操作都可以预测地修改原始游标。If you mix these calls on a single cursor, you may receive unexpected results.如果将这些调用混合在一个游标上,可能会收到意外的结果。
Because asynchronous calls directly modify the cursor, executing asynchronous calls on a single cursor simultaneously can also cause undefined behavior. 由于异步调用直接修改游标,因此同时对单个游标执行异步调用也可能导致未定义的行为。Always wait for the previous asynchronous operation to complete before running another.始终等待上一个异步操作完成,然后再运行另一个。
When you reach the last result through iteration or through an at-once fetch, the cursor is exhausted which means it ceases to respond to methods that access the results.当您通过迭代或一次获取获得最后一个结果时,游标将耗尽,这意味着它将停止响应访问结果的方法。
Asynchronous Iteration异步迭代
Cursors implement the AsyncIterator游标实现了AsyncIterator interface, which allows you to use cursors in
for await...of
loops:接口,它允许您在
for await...of
循环中使用游标:
const cursor = myColl.find({});
console.log("async");
for await (const doc of cursor) {
console.log(doc);
}
Manual Iteration手动迭代
You can use the hasNext()您可以使用 method to check if a cursor can provide additional data, and then use the next()
method to retrieve the subsequent element of the cursor:
hasNext()
方法来检查游标是否可以提供额外的数据,然后使用
next()
方法检索游标的后续元素:
const cursor = myColl.find({});
while (await cursor.hasNext()) {
console.log(await cursor.next());
}
Return an Array of All Documents返回所有文档的数组
For use cases that require all documents matched by a query to be held in memory at the same time, use the toArray()对于要求查询匹配的所有文档同时保存在内存中的用例,请使用 method.
toArray()
方法。
Note that large numbers of matched documents can cause performance issues or failures if the operation exceeds memory constraints. 请注意,如果操作超出内存限制,大量匹配的文档可能会导致性能问题或失败。Consider using the 考虑使用for await...of
syntax to iterate through results rather than returning all documents at once.for await...of
语法来迭代结果,而不是一次返回所有文档。
const cursor = myColl.find({});
const allValues = await cursor.toArray();
Stream API
Cursors expose the 游标公开stream()
method to convert them to Node Readable Streams. stream()
方法,将它们转换为Node Readable Streams。These streams operate in Object Mode, which passes JavaScript objects rather than Buffers or Strings through the pipeline.这些流在对象模式下运行,该模式通过管道传递JavaScript对象,而不是缓冲区或字符串。
const cursor = myColl.find({});
cursor.stream().on("data", doc => console.log(doc));
Event API
As Readable Streams, cursors also support the Event API's 作为可读流,游标还支持Event API的close
, data
, end
and readable
events:close
、data
、end
和readable
事件:
const cursor = myColl.find({});
// the "data" event is fired once per document
cursor.on("data", data => console.log(data));
Cursor Utility Methods游标实用程序方法
Rewind
To reset a cursor to its initial position in the set of returned documents, use rewind().要将游标重置到返回文档集中的初始位置,请使用rewind()
。
const cursor = myColl.find({});
const firstResult = await cursor.toArray();
console.log("First count: " + firstResult.length);
await cursor.rewind();
const secondResult = await cursor.toArray();
console.log("Second count: " + secondResult.length);
Close
Cursors consume memory and network resources both in the client application and in the connected instance of MongoDB. 游标消耗客户端应用程序和MongoDB连接实例中的内存和网络资源。Use close()使用 to free up a cursor's resources in both the client application and the MongoDB server:
close()
释放客户端应用程序和MongoDB服务器中的游标资源:
await cursor.close();