2016-02-26 63 views
2

以下是我的一個收集響應,wan't從以下收集更新庫存值..想要更新二級數組對象MongoDB中

{ 
    "_id": ObjectId(), 
    "sku": "V4696-DR-V33", 
    "options": [ 
     { 
      "sku": "8903689984338", 
      "stores": [ 
       { 
        "code": "AND1", 
        "zipcode": "110070", 
        "id" : 101010, 
        "inventory": 12 
       }, 
       { 
        "code": "AND2", 
        "zipcode": "201010", 
        "id" : 101010, 
        "inventory": 10 
       } 
      ], 
      "price": 2199, 
      "_id": ObjectId(), 
      "size": "14" 
     }, 
     { 
      "sku": "1742564789", 
      "stores": [ 
       { 
        "code": "AND1", 
        "zipcode": "110070", 
        "id" : 101010, 
        "inventory": 21 
       }, 
       { 
        "code": "AND2", 
        "zipcode": "201010", 
        "id" : 101010, 
        "inventory": 20 
       } 
      ], 
      "price": 2199, 
      "_id": ObjectId(), 
      "size": "16" 
     }, 
    ] 
} 

要更新所有存貨價值爲0,那麼應該怎麼得做..? 想要的任何簡單或單蒙戈查詢來更新我的所有文件..

回答

1

不可能的原子更新,只要你想更新嵌入一個嵌套的結構,即positional $ update operator將無法​​內場達到,如果使用單更新操作使用這種位置操作符來標識數組元素的位置。有一個超出的問題在此http://jira.mongodb.org/browse/SERVER-1243

作爲一種解決方法,您將需要循環訪問光標和光標內的每個文檔,收集關於庫存字段索引位置的數據。然後,您將在循環中稍後使用此數據作爲更新操作參數,以正確標識要更新的所需字段。

如果您收藏是不是堆積如山,上面的直覺可以使用光標的forEach()方法做迭代和獲取索引數據爲所有參與的陣列來實現。下面演示了這種方法對小數據集(假設您的收藏被命名爲inventory):

db.inventory.find({"options.stores.inventory": { "$exists": true, "$ne": 0 }}).forEach(function(doc){ 
    var options = doc.options; 
    for (var optionIndex = 0; optionIndex < options.length; optionIndex++){ 
     var stores = options[optionIndex].stores 
     for (var storeIndex = 0; storeIndex < stores.length; storeIndex++){ 
      var updateOperatorDocument = {}; 
      updateOperatorDocument["options."+optionIndex+".stores."+storeIndex+".inventory"] = 0 
      db.inventory.update(
       { "_id": doc._id }, 
       { "$set": updateOperatorDocument } 
      ); 
     }   
    } 
}); 

對於特別大的集合打交道時提高性能,需要使用Bulk() API的優勢,爲更新集合因爲您將批量發送操作到服務器(例如批量大小爲500)。由於您不會向服務器發送每個請求,而只會在每500次請求中發送一次請求,因此可以提供更好的性能,從而使您的更新更加高效快捷。

下面的例子演示如何使用MongoDB中的版本>= 2.6< 3.2可用Bulk() API。

var bulkUpdateOps = db.inventory.initializeUnOrderedBulkOp(), 
    counter = 0; 

db.inventory.find({"options.stores.inventory": { "$exists": true, "$ne": 0 }}).forEach(function(doc){ 
    var options = doc.options; 
    for (var optionIndex = 0; optionIndex < options.length; optionIndex++){ 
     var stores = options[optionIndex].stores 
     for (var storeIndex = 0; storeIndex < stores.length; storeIndex++){ 
      var updateOperatorDocument = {}; 
      updateOperatorDocument["options."+optionIndex+".stores."+storeIndex+".inventory"] = 0 
      bulkUpdateOps.find({ "_id": doc._id }).update({ "$set": updateOperatorDocument }) 
     }   
    }  
    counter++; // increment counter for batch limit 
    if (counter % 500 == 0) { 
     // execute the bulk update operation in batches of 500 
     bulkUpdateOps.execute(); 
     // Re-initialize the bulk update operations object 
     bulkUpdateOps = db.inventory.initializeUnOrderedBulkOp(); 
    } 
}) 

// Clean up remaining operation in the queue 
if (counter % 500 != 0) { bulkUpdateOps.execute(); } 

下示例適用於新的MongoDB 3.2版,其具有自所述deprecatedBulk() API和提供一個較新的組使用bulkWrite()的API。

它使用相同的遊標同上,但產生具有使用相同forEach()光標方法給每個批量寫文件推到陣列的批量操作的陣列:

var cursor = db.inventory.find({"options.stores.inventory": { "$exists": true, "$ne": 0 }}), 
    bulkUpdateOps = []; 

cursor.forEach(function(doc){ 
    var options = doc.options; 
    for (var optionIndex = 0; optionIndex < options.length; optionIndex++){ 
     var stores = options[optionIndex].stores 
     for (var storeIndex = 0; storeIndex < stores.length; storeIndex++){ 
      var updateOperatorDocument = {}; 
      updateOperatorDocument["options."+optionIndex+".stores."+storeIndex+".inventory"] = 0 
      bulkUpdateOps.push({ 
       "updateOne": { 
        "filter": { "_id": doc._id }, 
        "update": { "$set": updateOperatorDocument } 
       } 
      }); 
     }   
    } 
});   

db.inventory.bulkWrite(bulkUpdateOps); 

寫入結果對於樣品數據

{ 
    "acknowledged" : true, 
    "deletedCount" : 0, 
    "insertedCount" : 0, 
    "matchedCount" : 4, 
    "upsertedCount" : 0, 
    "insertedIds" : {}, 
    "upsertedIds" : {} 
} 
+1

感謝您爲我提供這個信息..這對我真的很有幫助... –