我只是习惯了承诺,我想在表格中添加额外的ObjectId引用。我使用这段代码:
'use strict';
const mongoose = require('mongoose');
const config = require('config');
mongoose.connect(config.get("DBUrl"), {useMongoClient: true});
mongoose.set('debug', true);
require('../model/AnnotationRequest');
require('../model/Website');
const AnnotationRequest = mongoose.model('AnnotationRequest');
const Website = mongoose.model('Website');
foo(function () {
console.log('done');
});
function foo(done) {
Website.find()
.then(function (websites) {
if (!websites) console.error('could not find any websites');
AnnotationRequest.find({website: {$exists: false}})
.then(function (annotationRequests) {
let jobs = [];
for (let k = 0; k < annotationRequests.length; k++) {
let found = false;
for (let i = 0; i < websites.length; i++) {
let websiteAnnotations = websites[i].annotations;
for (let o = 0; o < websiteAnnotations.length; o++) {
if (websiteAnnotations[o].equals(annotationRequests[k].annotation)) {
found = true;
annotationRequests[k].website = websites[i];
jobs.push(
annotationRequests[k].save()
.then(function (res) {
console.log("success saving", res._id);
}).catch(function (err) {
console.error(err);
done(err);
})
);
break;
}
}
if (found) {
break;
}
}
}
Promise.all(jobs).then(
function () {
done();
}
).catch(function (err) {
console.error(err);
});
});
});
}
报告第一个保存查询是在Promise.all语句中启动的。在第一个.save()
语句之后是否应该立即执行查询?我怎样才能立即启动它们?
另一个问题是,对于200k条目,此代码需要2个小时。在服务器上我们有&gt; 2M条目。不确定它是否会起作用。有什么建议吗?
由于
答案 0 :(得分:2)
节点运行单线程,因此如果您有200k循环,则所有保存语句都会等待,直到您的代码同步执行并完成。
尝试使用异步模块使您的代码更加异步友好。 https://caolan.github.io/async/
尝试此代码,但此代码与您的代码有相同的错误。我有一个网站有相同的注释,你的设置首先找到,我可能最后找到。
'use strict';
const mongoose = require('mongoose');
const config = require('config');
const async = require('async');
mongoose.connect(config.get("DBUrl"), {useMongoClient: true});
mongoose.set('debug', true);
require('../model/AnnotationRequest');
require('../model/Website');
const AnnotationRequest = mongoose.model('AnnotationRequest');
const Website = mongoose.model('Website');
foo(function () {
console.log('done');
});
function foo(done) {
const pageSize= 10000;
async.parallel([function(callback) {
Website.find().then( function(websites) {
callback(null, websites);
}).catch(callback);
},function(callback) {
AnnotationRequest.count({website: {$exists: false}}).then( function(count) {
callback(null, count);
}).catch(callback);
}], function(err, results) {
if(err) {
console.error(err);
return;
}
const websites = results[0];
const annotationRequestsCount = results[1];
let websiteAnnotationMap = {};
websites.forEach(function (website) {
website.annotations.forEach(function (annotation) {
websiteAnnotationMap[annotation] = website;
});
});
var skip = 0;
async.during(
function (callback) {
return callback(null, skip < annotationRequestsCount);
},
function (callback) {
AnnotationRequest.find({website: {$exists: false}}, { skip: skip, limit: pageSize })
.then( function(annotationRequests) {
skip += pageSize;
async.each(annotationRequests, function(annotationRequest, eachCallback) {
let website = websiteAnnotationMap[annotationRequest.annotation];
if(website) {
annotationRequest.website = website;
annotationRequest.save().then(function () {
eachCallback();
}).catch(eachCallback);
} else {
eachCallback();
}
}, callback);
}).catch(callback);
},
done
);
});
}