2017-03-24 106 views
0

我有一個具有唯一索引的MongoDB集合。 我正在嘗試將文檔數組插入或更新到該集合中。MongoDb:插入或更新具有唯一索引的多個文檔

如果集合中沒有與文檔的唯一索引相匹配的現有文檔,則應將該新文檔插入到集合中。

但是,如果已有集合中的文檔具有該唯一索引,則應該使用新文檔的字段進行更新。任何不在新文檔中的字段都應該保持不變。

這是我目前正在插入(但不是更新)的工作。

const mongojs = require('mongojs'); 
const db = mongojs('mongodb://username:[email protected]:37230/database'); 

      // items is an array of documents 
db.items.insert(items, (err, task) => { 
    if (err) { 
     console.log(err); 
    } 
    }) 

我明白這是錯誤的,它目前給出了這個錯誤:

E11000 duplicate key error index: database.items.$upc_1 dup key:

,這是什麼正確的查詢?

+0

您是否收到錯誤消息? –

+0

首先,只需使用MongoDB的本地NodeJS驅動程序。其次,你想使用Upsert,而不是插入。 –

+0

從原始文章中不清楚您使用的是本機驅動程序。 mongojs本身就是一個NPM模塊。你應該在你的例子中顯示你需要的語句。 –

回答

2

我不相信你可以在同一時間更新的文檔的整個陣列。因此,您必須逐個更新數組中的每個項目。如果記錄存在

items.forEach((item) => { 
    db.items.update({_id: item._id}, item, {upsert: true}, (err, task) => { 
      if (err) { 
      console.log(err); 
      } 
    }); 
} 

{upsert: true}選項將更新,如果沒有插入。

+0

感謝泰勒。我目前正在使用遠程託管服務mLab。如果我有十個文件,採用這種方法我必須做十個獨立的電話。有沒有更好的辦法? – etayluz

+0

如果你也可以在這個問題:https://stackoverflow.com/questions/42990854/mo​​ngodb-insert-multiple-documents-into-collection-with-unique-index-even-if-som – etayluz

+0

不是我的知識。有一個updateMany函數,但它會更新所有匹配給定查詢選擇器的文檔。我不相信這是你正在尋找的。 –

0

你在找什麼是一個upsert,而不是插入。它可以通過下面的代碼來完成:

db.collection.update(
    <query>, 
    <updates>, 
    { 
    upsert: <boolean>, 
    multi: <boolean>, 
    writeConcern: <document>, 
    collation: <document> 
    } 
) 

查詢將搜索使用的查詢參數的文件,如果找到,它會更新中提到的領域。如果找不到,它會插入一個新的文檔,其中的字段和值爲。

最後一個對象(包含多個字段)包含一個字段,用於說明是否需要upsert,以及一個名爲「multi」的字段用於說明是否需要更新多個文檔。

例如:

db.items.update({name:"item1"},{$set:{price:20}},{upsert:true}) 

這將搜索名爲「物品1」的文件,其價格設定爲20。如果沒有找到,它會創建一個新的同價位20。

有一點要注意,雖然是:

如果不使用標籤$集上的字段,它將替代整個文檔。

假設你有一個這樣的文件:

{_id:"1234",name:"item1",price:10} 

如果您運行以下兩個查詢:

db.items.update({name:"item1"},{$set:{price:20}},...) 

db.items.update({name:"item1"},{price:20},...) 

它將yeld不同的結果:

第一種:

{_id:"1234",name:"item1",price:20} 

第二個:

{_id:"1234",price:20} 

如果你不叫$set,它將改變整個文檔。說明書上

的更多信息:

https://docs.mongodb.com/manual/reference/method/db.collection.update/

希望我的回答對您有所幫助

+0

謝謝,但只有一個文件?我有一系列文件。 – etayluz

+0

現在更新我的答案 –

+0

這太棒了!但我的問題是如何做到這一點的文件數組。 – etayluz

1

您可以嘗試使用MongoDB的bulkWrite API:

var ops = [] 

items.forEach(item => { 
    ops.push(
     { 
      updateOne: { 
       filter: { _id: unique_id }, 
       update: { 
        $set: { fields_to_set_if_exists }, 
        $setOnInsert: { fileds_to_insert_if_does_not_exist } 
       }, 
       upsert: true 
      } 
     } 
    ) 
}) 

db.collections('collection_name').bulkWrite(ops, { ordered: false }); 
相關問題