2016-12-30 27 views
4

我在嘗試爲此編寫邏輯時遇到了一些問題。所以,我想要做的是:使用upsert進行更新,但僅在db中文檔的日期字段少於更新文檔時才更新

  • 批量更新一堆職位到我的遠程MongoDB實例但
  • 如果更新,僅當遠程採集lastModified場是在同一個不到lastModified字段更新文件,我即將更新/插入

基本上,我想更新我的文件列表,如果他們已被修改,因爲我上次更新他們。 我能想到兩個蠻力的方式來做到這一點...

首先,查詢我的整個集合,試圖手動刪除和替換符合條件的文件,添加新的,然後插入質量回來的一切刪除遠程中的所有內容後刪除遠程集合。

二,查詢每個項目,然後決定,如果有一個在遠程,如果我想更新它或否。這似乎是處理遠程集合時的任務。

如果相關,我正在研究NodeJS環境,使用mondodb npm包進行數據庫操作。

+0

您是否正在使用另一個集合中的值更新文檔? – styvane

+0

不,我正在將http呼叫的值收集到外部服務。 –

回答

0

您可以使用bulkWrite API根據您指定的邏輯執行更新,因爲它可以更好地處理此更新。

例如,下面的片段展示瞭如何去了解這個假設已經從Web服務中的數據,你需要更新遠程採集:

mongodb.connect(mongo_url, function(err, db) { 
    if(err) console.log(err); 
    else { 
     var mongo_remote_collection = db.collection("remote_collection_name"); 

     /* data is from http call to an external service or ideally 
      place this within the service callback 
     */ 
     mongoUpsert(mongo_remote_collection, data, function() { 
      db.close(); 
     }) 
    } 
}) 

function mongoUpsert(collection, data_array, cb) {  
    var ops = data_array.map(function(data) { 
     return { 
      "updateOne": { 
       "filter": { 
        "_id": data._id, // or any other filtering mechanism to identify a doc 
        "lastModified": { "$lt": data.lastModified } 
       }, 
       "update": { "$set": data }, 
       "upsert": true 
      } 
     }; 
    }); 

    collection.bulkWrite(ops, function(err, r) { 
     // do something with result 
    }); 

    return cb(false); 
} 

如果從數據外部服務是巨大的,然後考慮將批量寫入服務器的數量爲500,這樣可以提供更好的性能,因爲您不會向服務器發送每個請求,只需要每500次請求一次。

批量操作MongoDB的規定每批1000的default internal limit作業等的500個文件的選擇是,你必須在批量大小一定的控制,而不是讓MongoDB的徵收默認情況下,即在較大的操作感良好> 1000文件的大小。所以對於第一種方法中的上述情況,可以一次寫入所有的數組,因爲這很小,但是500選擇是針對較大的數組。

​​
+0

在這種情況下,沒有滿足使用ID但lastmodified條件找到的文檔(本地lastmodified小於remote的lastModified),仍將插入到集合中,它們不會嗎?因爲它們不屬於過濾器參數 –

+0

是的,'{upsert:true}'方法可以保證。刪除該選項意味着如果沒有滿足帶有ID但「lastModified」條件的文檔,則不會進行更新。如果查詢不滿足,則使用'{upsert:true}'來插入文檔。 – chridam

+0

這是一個問題,我希望做的是插入,如果沒有ID匹配,但不插入,如果本地lastModified是少於遠程lastModified。基本上,如果一個過濾器或另一個過濾器過濾器會有不同的動作。 –