Aqui está uma comparação entre
toArray()
e cursores após um find()
no driver Node.js MongoDB. Código comum: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
});
Aqui está o
toArray()
código que vai na seção acima. 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();
});
Pela documentação,
O chamador é responsável por garantir que haja memória suficiente para armazenar os resultados.
Aqui está a abordagem baseada em cursor, usando o
cursor.forEach()
método: 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();
}
);
});
Com o
forEach()
abordagem, em vez de buscar todos os dados na memória, estamos transmitindo os dados para nosso aplicativo. find()
cria um cursor imediatamente porque não faz uma solicitação ao banco de dados até que tentemos usar alguns dos documentos que ele fornecerá. O ponto do cursor
é descrever nossa consulta. O segundo parâmetro para cursor.forEach
mostra o que fazer quando ocorre um erro. Na versão inicial do código acima, era
toArray()
que forçou a chamada do banco de dados. Isso significava que precisávamos de TODOS os documentos e queria que eles estivessem em um array
. Observe que
MongoDB
retorna dados em lotes. A imagem abaixo mostra solicitações de cursores (do aplicativo) para MongoDB
:forEach
escala melhor que toArray
porque podemos processar documentos à medida que eles chegam até chegarmos ao fim. Compare com toArray
- onde esperamos por TODOS os documentos a serem recuperados e a toda matriz é construída. Isso significa que não estamos obtendo nenhuma vantagem do fato de que o driver e o sistema de banco de dados estão trabalhando juntos para agrupar os resultados em seu aplicativo. O lote destina-se a fornecer eficiência em termos de sobrecarga de memória e tempo de execução. Aproveite-o em seu aplicativo, se puder.