我有150.000个元素的集合。它的大小不到150MB。 出于测试原因,我想把它放到数组中。这是相对少量的数据,所以我希望它应该没有任何问题。不是这样。
我之前的编辑是关于shell和NodeJS之间的区别,但我认为现在不是这一点,所以我编辑了帖子以代表更有趣的问题。
Rig:我的驱动程序版本是3,Mongo版本是3.6。我使用最新的NodeJS作为主要工具。 8GB RAM。
因此,有两种基本方法可以将集合项目添加到数组中。
测试脚本(使用时刻)
exports.testMongoLoad = function() {
console.log("started");
var m1 = moment();
testMongoLoad2(function(err, docs) {
if (err) console.log(err);
var m2 = moment();
console.log(
"Returned " +
docs.length +
" documents in " +
m2.diff(m1, "ms") +
" ms as array"
);
});
};
toArray()函数
testMongoLoad1 = function(callback) {
db
.get()
.collection("matchesn")
.find({})
.toArray(function(err, docs) {
if (err) return callback(err);
return callback(null, docs);
});
};
~8秒
每个()函数
testMongoLoad2 = function(callback) {
docs = [];
db
.get()
.collection("matchesn")
.find({})
//.project({ _id: 1 })
.each(function(err, doc) {
if (doc) {
docs.push(doc);
} else {
return callback(null, docs);
}
});
};
~8秒
如果我使用project
,我会在 ~1秒内获得结果。
如果我只使用150000个元素填充一些数组(请参阅我的评论),它将在 ~60 ms完成
那么,正确的方法是什么?可以这样做,还是100%禁止驱动程序级别进行此类操作?
UPD
基本上toArray
实施正在执行next
,直到什么都没有
toArray source code
var toArray = function(self, callback) {
var items = [];
// Reset cursor
self.rewind();
self.s.state = Cursor.INIT;
// Fetch all the documents
var fetchDocs = function() {
self._next(function(err, doc) {
if (err) return handleCallback(callback, err);
if (doc == null) {
return self.close({ skipKillCursors: true }, () => handleCallback(callback, null, items));
}
// Add doc to items
items.push(doc);
// Get all buffered objects
if (self.bufferedCount() > 0) {
var docs = self.readBufferedDocuments(self.bufferedCount());
// Transform the doc if transform method added
if (self.s.transforms && typeof self.s.transforms.doc === 'function') {
docs = docs.map(self.s.transforms.doc);
}
push.apply(items, docs);
}
// Attempt a fetch
fetchDocs();
});
};
fetchDocs();
};