2017-03-24 102 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 }); 
相关问题