将Meteor中的值插入MongoDB的速度令人难以置信,机器没有任何负载。
我从db获取一个值并删除_id以生成一个新值并将该值再次插入到db中。
Meteor.methods({
testInsert() {
const id = ID.find({ Project: Number(287), ID: Number(169372), Deleted: false }).fetch();
if (id === undefined || id === '' || id.length > 1 || id.length === 0) {
throw new Meteor.Error('no unique id found');
}
console.log('got ID ' + id[0].ID);
const oldId = id[0]._id;
delete id[0]._id;
try {
console.log('Start inserting ... ' + new Date());
ID.insert(id[0]);
console.log('Done inserting ' + new Date());
} catch (e) {
throw new Meteor.Error('error inserting`);
}
console.log('Done single');
},
});
结果:
得到ID 169372
开始插入... 2016年11月18日星期五12:25:59 GMT + 0100(CET)
完成插入2016年11月18日星期五12:26:09 GMT + 0100(CET)
插入需要10秒钟!我插入的JSON是14kb大或相当小。插入在mongo的shell(命令行)中不到一秒钟。这段代码过去足够快。我桌上也有一个索引。
ID._ensureIndex({ Deleted: 1, ID: 1 });
要明确的是,目前任何插入都很慢,而不仅仅基于上面的示例代码。但奇怪的是,对于一个简单的插入,节点/流星运行的机器上的负载达到100%!有什么想法吗?
更新
MongoDB不是在我的本地开发人员计算机上运行,而是在专用数据库服务器上,我使用隧道(如果你想知道为什么错误消息称为localhost :))
更新2:
当我使用for循环插入10个ID流星崩溃时,虽然流星恢复它需要5-10分钟,但它实际上写了所有数据
Exception while polling query {"collectionName":"id","selector":{"id":287,"Deleted":false},"options":{"transform":null}}: MongoError: connection 7 to localhost:27017 timed out
更新3:
我将MongoDB更新为3.2但仍然有例外。
Exception while polling query {"collectionName":"ID","selector":{"ID":287,"Deleted":false},"options":{"transform":null}}: MongoError: connection 17 to localhost:27017 timed out
更新4:
轮询错误/超时与我认为的问题无关,这就是我删除堆栈跟踪的原因。我能够构建一个通用的测试用例来复制这个问题。似乎mongo节点/流星驱动程序无法很好地处理数组属性。我已将带有Java驱动程序的条目插入到mongo中,没有任何问题。我创建了一个测试用例,用500个随机条目填充数组。这个插入语句大约需要10秒钟。通过增加ID的数量,您还将遇到超时错误。
Meteor.methods({
testInsert() {
const testIDs = [
{ ID: 100000, array: [] },
{ ID: 200000, array: [] }];
function makeTestCase(id) {
for (let i = 0; i < 500; i += 1) {
id.array.push({
"Date": new Date,
"Text1" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
"Text2" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
"Text3" : "Lorem ipsum dolor sit amet, consectetur adipisicing elit.",
"Text4" : i,
"Text5" : i,
"Text6" : i,
"Text7" : i,
});
}
}
testIDs.forEach(makeTestCase);
function insertID(id) {
try {
console.log(`Start inserting ... ${new Date()}`);
BshID.insert(id, { validate: false });
console.log(`Done inserting ${new Date()}`);
} catch (e) {
throw new Meteor.Error('ID ERROR');
}
}
testIDs.forEach(insertID);
console.log('all done');
}
});
答案 0 :(得分:0)
您可以做一些改进:
ID
字段 如果我正确理解了您的代码,您始终会搜索最旧的记录来生成新文档。如果您创建降序索引,MongoDB会更快地找到您的文档,因为它会优化您的索引以首先查看ID
的最高值。
另外,如果您始终按Project
和ID
进行搜索,则还应在索引中包含Project
。
首先,删除最旧的索引:
ID._dropIndex({Deleted: 1, ID: 1})
然后,创建新索引:ID._ensureIndex({Deleted: 1, ID: -1, Project: -1})
如果您只需要一个文档,请使用findOne
查找此文档,MongoDB无需查看所有记录即可获取结果。此外,您可以将fields
属性添加到findOne
,只告诉Meteor在此操作中与您相关的字段,但是看到您的示例,您正在创建文档的副本,所以情况并非如此。
ID.findOne({
Project: Number(287),
ID: Number(169372),
Deleted: false
});
您正在使用Meteor 1.4,因此您应该将MongoDB更新为与此Meteor版本兼容的相应版本。查看http://info.meteor.com/blog/announcing-meteor-1.4了解详情。
进一步阅读