[英]node.js compare two arrays with objects
我需要從mongo數據庫中刪除所有文檔,這些文檔不存在於帶有對象的新數組中。 所以我有對象數組:
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'}];
並且我有通過調用Model.find({})獲得的帶有db值的數組。 因此,現在我以“直接”方式進行操作:
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();
});
}
});
但是它阻塞了整個應用程序,而且速度很慢,因為我的items數組和數據庫中也有大約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個周期。 所以也許有人可以建議我一些事情?
在您可能遇到的許多問題中,您可能想通過更改以下內容來開始:
Product.remove({ _id: dbProduct._id }, function (err) {
if (err) return updateDBCallback(err);
callback();
});
在.each()
調用中,您將對要刪除的每個元素進行一次數據庫調用。 最好將所有id存儲在一個數組中,然后進行單個查詢以刪除該數組中具有_id的所有元素。 像這樣
Product.remove({ _id: {$in: myArrayWithIds} }, function (err) {
if (err) return updateDBCallback(err);
callback();
});
另一個要注意的是,由於async
將同步執行,所以node.js確實提供了setImmediate()
( 此處為文檔),它將在事件循環內執行該函數。 因此,基本上,您可以“暫停”新元素的執行,並處理所有傳入請求以模擬“非阻塞”處理。
在異步庫不以異步方式執行同步代碼。
5000個項目對於JavaScript來說並不是一個很大的數目,因為我已經研究了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
});
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.