从游标中访问数据
概述
在本指南中,您可以了解如何使用 Kotlin Sync 驱动程序从 游标 中访问数据。
游标是一种机制,用于以可迭代批次的格式返回读操作的结果。由于游标在任何给定时间只保留文档的子集,因此游标可以减少内存消耗和驱动程序发送给服务器的请求数量。
每当 Kotlin Sync 驱动程序执行返回多个文档的读操作时,它都会自动以游标的形式返回这些文档。
示例数据
本指南中的示例使用restaurants
集合,该集合位于 sample_restaurants
数据库中,该数据库来自Atlas 示例数据集。要了解如何创建免费的 MongoDB Atlas 集群并加载数据集,请参阅 Atlas 入门指南。
以下 Kotlin 数据类模型表示此集合中的文档
data class Restaurant( val id: ObjectId, val name: String )
迭代访问游标内容
要迭代游标的内容,请使用 forEach()
方法,如下例所示
val results = collection.find() results.forEach { result -> println(result) }
或者,使用 use()
方法在游标上实现循环
val results = collection.find() results.cursor().use { cursor -> while (cursor.hasNext()) { println(resultCursor.next()) } }
注意
默认情况下,当客户端耗尽游标中的所有结果时,MongoDB 会关闭游标。本指南中的示例通过使用 close()
方法显式关闭游标。
单独检索文档
通过调用 next()
方法单独从游标中检索文档。
以下示例找到所有 name
值为 "Dunkin' Donuts"
的集合中的文档。然后通过调用 next()
方法打印游标中的第一个文档。
val results = collection .find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts")) results.cursor().use { cursor -> println(if (cursor.hasNext()) cursor.next() else "No document matches the filter") }
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts)
检索所有文档
警告
如果查询返回的文档数量和大小超过了可用应用程序内存,您的程序将会崩溃。如果您预期结果集很大,请迭代地访问您的游标。
要检索游标中的所有文档,请将游标转换为以下示例中所示的List
val results = collection.find<Restaurant>(eq(Restaurant::name.name, "Dunkin' Donuts")) val resultsList = results.toList() for (result in resultsList) { println(result) }
Restaurant(id=5eb3d668b31de5d588f42c66, name=Dunkin' Donuts) Restaurant(id=5eb3d668b31de5d588f42ca0, name=Dunkin' Donuts) Restaurant(id=5eb3d668b31de5d588f42b08, name=Dunkin' Donuts) Restaurant(id=5eb3d668b31de5d588f42cd7, name=Dunkin' Donuts) ...
可变长游标
在查询有界集合时,可以使用在客户端耗尽游标结果后仍然保持打开状态的可变长游标。要创建带有有界集合的可变长游标,将CursorType.TailableAwait
指定给FindIterable
对象的cursorType
方法。
以下示例创建了一个有界集合上的可变长游标
val results = collection.find<Document>().cursorType(CursorType.TailableAwait)
有关可变长游标及其使用的更多信息,请参阅MongoDB服务器手册中的可变长游标指南。
故障排除
"CursorNotFound cursor id not valid at server"
在MongoDB中,如果游标长时间打开而没有进行任何操作,它们在服务器上可能会超时。当你尝试遍历游标时,这可能会导致抛出 CursorNotFound
异常。
API 文档
要了解更多关于本指南中讨论的任何方法或类型的信息,请参阅以下API文档