资讯专栏INFORMATION COLUMN

MongoCursor简单总结

fjcgreat / 1728人阅读

摘要:要不要显式关闭查询数据实现一实现二实现二更方便简洁但是没有显式关闭有没问题呢一些结论如果已被遍历完会自动关闭无需显式关闭所以实现二没有问题如果只是遍历了部分数据需要显式关闭在遍历过程中同时处理其他业务逻辑需要在中关闭避免中间报了异常没有迭代

cursor要不要显式关闭

Mongo查询数据实现一

MongoCursor cursor = collection.find().limit(limit).iterator();
List documentList = new ArrayList<>();
try {
    while (cursor.hasNext()) {
        T document = cursor.next();
        documentList.add(document);
    }
} finally {
    cursor.close();
}
return documentList;

实现二

return newArrayList(collection.find().limit(limit));

实现二更方便简洁 但是没有显式关闭cursor有没问题呢?

一些结论

如果cursor已被遍历完(exhausted) 会自动关闭 无需显式关闭 所以实现二 没有问题

By default, the server will automatically close the cursor after 10
minutes of inactivity, or if client has exhausted the cursor.

https://docs.mongodb.com/manu...

如果只是遍历了部分数据 需要显式关闭

MongoCursor mongoCursor = coll.find().sort(ascending("_id")).iterator();
Document doc1 = mongoCursor.next();
// ...
mongoCursor.close();

在遍历过程中 同时处理其他业务逻辑 需要try catch在finally中关闭 避免中间报了异常 没有迭代完 导致cursor泄露

cursor泄露的危害

Leaving a "cursor" open is like leaving an open connection that never gets re-used. These things are not free. In fact the standard connection cost is 1MB (approx). So if you are leaving a lot of "partially iterated" cursors hanging around there is a general overhead in terms of an active connection and it"s memory usage.
https://stackoverflow.com/que...
一次性查询出来 VS 逐个迭代

一次性查询出来放到list中

return newArrayList(collection.find().limit(500))

直接将500个对象放到内存中了

逐个迭代

MongoCursor cursor = collection.find().limit(500).iterator();
try {
    while (cursor.hasNext()) {
        T document = cursor.next();
        // business logic here ...
        documentList.add(document);
    }
} finally {
    cursor.close();
}

Mongo底层是分批查询的 先是查出101个对象 再接着查出剩下的399个对象 相比一次性查出内存中最多有399个对象

find() and aggregate() operations have an initial batch size of 101
documents by default. Subsequent getMore operations issued against the
resulting cursor have no default batch size, so they are limited only
by the 16 megabyte message size.

如果觉得399个对象还是大了 可以显式指定每批查询多少 如可以指定每批查100个 如下所示

MongoCursor mongoCursor = coll.find().limit(500).batchSize(100).iterator();

但是这会增加网络交互次数 本来默认查两次 现在变成了查5次了

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/19248.html

相关文章

  • MongoCursor简单总结

    摘要:要不要显式关闭查询数据实现一实现二实现二更方便简洁但是没有显式关闭有没问题呢一些结论如果已被遍历完会自动关闭无需显式关闭所以实现二没有问题如果只是遍历了部分数据需要显式关闭在遍历过程中同时处理其他业务逻辑需要在中关闭避免中间报了异常没有迭代 cursor要不要显式关闭 Mongo查询数据实现一 MongoCursor cursor = collection.find().limit(l...

    Sourcelink 评论0 收藏0
  • MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据

    摘要:前两篇教程我们介绍了如何搭建的本地环境最简单的入门教程之一环境搭建以及如何用读取里的记录最简单的入门教程之二使用访问这篇教程我们会介绍如何使用代码来连接。代码如下和教程二相比,上述代码的方法里还展示了如何用代码给数据库里增加记录。 前两篇教程我们介绍了如何搭建MongoDB的本地环境: MongoDB最简单的入门教程之一 环境搭建 以及如何用nodejs读取MongoDB里的记录: M...

    Kylin_Mountain 评论0 收藏0
  • MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据

    摘要:前两篇教程我们介绍了如何搭建的本地环境最简单的入门教程之一环境搭建以及如何用读取里的记录最简单的入门教程之二使用访问这篇教程我们会介绍如何使用代码来连接。代码如下和教程二相比,上述代码的方法里还展示了如何用代码给数据库里增加记录。 前两篇教程我们介绍了如何搭建MongoDB的本地环境: MongoDB最简单的入门教程之一 环境搭建 以及如何用nodejs读取MongoDB里的记录: M...

    Hegel_Gu 评论0 收藏0
  • MongoDB最简单的入门教程之三 使用Java代码往MongoDB里插入数据

    摘要:前两篇教程我们介绍了如何搭建的本地环境最简单的入门教程之一环境搭建以及如何用读取里的记录最简单的入门教程之二使用访问这篇教程我们会介绍如何使用代码来连接。代码如下和教程二相比,上述代码的方法里还展示了如何用代码给数据库里增加记录。 前两篇教程我们介绍了如何搭建MongoDB的本地环境: MongoDB最简单的入门教程之一 环境搭建 以及如何用nodejs读取MongoDB里的记录: M...

    whatsns 评论0 收藏0

发表评论

0条评论

fjcgreat

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<