我需要从我的mongo db中删除所有文件,这些文件在带有对象的新数组中不存在。 所以我有像以下对象的数组:
var items = [
{product_id:15, pr_name: 'a', description : 'desc'},
{product_id:44, pr_name: 'b', description : 'desc2'}
{product_id:32, pr_name: 'c', description : 'desc3'}];
我有一个带有db值的数组,我可以通过调用 Model.find({})获得。 所以现在我直接做到这一点。方式:
async.each(products, function (dbProduct, callback) { //cycle for products removing
var equals = false;
async.each(items, function(product, callback){
if (dbProduct.product_id === product.product_id){
product.description = dbProduct.description;// I need to save desc from db product to new product
equals = true;
}
callback();
});
if (!equals) {
log.warn("REMOVE PRODUCT " + dbProduct.product_id);
Product.remove({ _id: dbProduct._id }, function (err) {
if (err) return updateDBCallback(err);
callback();
});
}
});
但它阻止了整个应用程序并且非常慢,因为我的 项目 数组和数据库中的值大约为5000。因此它的周期数非常庞大。 也许可以有更快的方式?
UPDATE1 使用以下代码,来自 TbWill4321 回答:
var removeIds = [];
// cycle for products removing
async.each(products, function (dbProduct, callback) {
for ( var i = 0; i < items.length; i++ ) {
if (dbProduct.product_id === product.product_id) {
// I need to save desc from db product to new product
product.description = dbProduct.description;
// Return early for performance
return callback();
}
}
// Mark product to remove.
removeIds.push( dbProduct._id );
log.warn("REMOVE PRODUCT " + dbProduct.product_id);
return callback();
}, function() {
Product.remove({ _id: { $in: removeIds } }, function (err) {
if (err) return updateDBCallback(err);
// Continue Here.
// TODO
});
});
它需要大约11秒(阻止整个网络应用程序)并为我带来12 362 878个周期。 那么也许有人可以给我一些建议?
答案 0 :(得分:1)
在您可能遇到的许多问题中,您可能希望从更改此位开始:
Product.remove({ _id: dbProduct._id }, function (err) {
if (err) return updateDBCallback(err);
callback();
});
在.each()
电话中,您将为要删除的每个元素拨打一次数据库。最好将所有ID存储在 one 数组中,然后进行单个查询以删除所有具有该数组中的_id的元素。喜欢这个
Product.remove({ _id: {$in: myArrayWithIds} }, function (err) {
if (err) return updateDBCallback(err);
callback();
});
另一方面,由于async
将同步执行,因此node.js提供了setImmediate()
(docs here),它将在事件循环中执行该函数。所以基本上你可以&#34;暂停&#34;执行新元素并提供任何传入请求以模拟&#34;非阻塞&#34;处理
答案 1 :(得分:1)
异步库不以异步方式执行同步代码。
对于JavaScript来说5000个项目并不是一个庞大的数字,因为我已经在500万+点的大数据集上工作,并且不需要很长时间。您可以通过以下结构获得更好的性能:
var removeIds = [];
// cycle for products removing
async.each(products, function (dbProduct, callback) {
for ( var i = 0; i < items.length; i++ ) {
if (dbProduct.product_id === product.product_id) {
// I need to save desc from db product to new product
product.description = dbProduct.description;
// Return early for performance
return callback();
}
}
// Mark product to remove.
removeIds.push( dbProduct._id );
log.warn("REMOVE PRODUCT " + dbProduct.product_id);
return callback();
}, function() {
Product.remove({ _id: { $in: removeIds } }, function (err) {
if (err) return updateDBCallback(err);
// Continue Here.
// TODO
});
});