gpt4 book ai didi

mongodb - 什么是 MongoDB 中的光标?

转载 作者:IT老高 更新时间:2023-10-28 13:04:58 25 4
gpt4 key购买 nike

我们对某些 Morphia 查询最终出现 cursor not found 异常 感到困扰 asList我找到了 hint on SO ,这可能会非常消耗内存。

现在我想了解更多关于背景的信息:有人能解释一下(用英语),Cursor(在 MongoDB 中)到底是什么吗?为什么它可以一直打开或找不到?


文档 defines光标为:

A pointer to the result set of a query. Clients can iterate through a cursor to retrieve results. By default, cursors timeout after 10 minutes of inactivity

但这不是很能说明问题。也许为查询结果定义一个 batch 可能会有所帮助,因为 documentation also states :

The MongoDB server returns the query results in batches. Batch size will not exceed the maximum BSON document size. For most queries, the first batch returns 101 documents or just enough documents to exceed 1 megabyte. Subsequent batch size is 4 megabytes. [...] For queries that include a sort operation without an index, the server must load all the documents in memory to perform the sort before returning any results.

注意:在我们所讨论的查询中,我们根本不使用排序语句,也没有使用 limitoffset

最佳答案

以下是 Node.js MongoDB 驱动程序中 toArray()find() 之后的游标之间的比较。常用代码:

var MongoClient = require('mongodb').MongoClient,
assert = require('assert');

MongoClient.connect('mongodb://localhost:27017/crunchbase', function (err, db) {
assert.equal(err, null);
console.log('Successfully connected to MongoDB.');

const query = { category_code: "biotech" };

// toArray() vs. cursor code goes here
});

这里是 toArray()上一节中的代码。

    db.collection('companies').find(query).toArray(function (err, docs) {
assert.equal(err, null);
assert.notEqual(docs.length, 0);

docs.forEach(doc => {
console.log(`${doc.name} is a ${doc.category_code} company.`);
});

db.close();
});

根据文档,

The caller is responsible for making sure that there is enough memory to store the results.

这是基于光标的方法,使用 cursor.forEach()方法:

    const cursor = db.collection('companies').find(query);

cursor.forEach(
function (doc) {
console.log(`${doc.name} is a ${doc.category_code} company.`);
},
function (err) {
assert.equal(err, null);
return db.close();
}
);
});

使用 forEach() 方法,我们不是在内存中获取所有数据,而是将数据流式传输到我们的应用程序。 find() 立即创建一个游标,因为它实际上不会向数据库发出请求,直到我们尝试使用它将提供的一些文档。 cursor 的重点是描述我们的查询。 cursor.forEach 的第二个参数显示了发生错误时的处理方式。

在上述代码的初始版本中,是 toArray() 强制数据库调用。这意味着我们需要 ALL 文档并希望它们位于 array 中。

注意 MongoDB 是分批返回数据的。下图显示了从游标(从应用程序)到 MongoDB 的请求:

MongoDB cursor graphic

forEachtoArray 具有更好的扩展性,因为我们可以在文档进入时处理,直到到达末尾。将其与 toArray 进行对比 - 我们等待 ALL 检索文档并构建 entire 数组。这意味着我们没有从驱动程序和数据库系统协同工作以将结果批处理到您的应用程序这一事实中获得任何优势。批处理旨在提高内存开销和执行时间方面的效率。 如果可以的话,在你的应用程序中利用它。

关于mongodb - 什么是 MongoDB 中的光标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36766956/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com