简体   繁体   English

MongoDb:插入或更新具有唯一索引的多个文档

[英]MongoDb: Insert or update multiple documents with a unique index

I have a MongoDB collection with a unique index. 我有一个具有唯一索引的MongoDB集合。 I am trying to insert or update an array of documents into that collection. 我正在尝试向该集合中插入或更新一系列文档。

If there is NO existing document in the collection matching the unique index of the document, that new document should be inserted into the collection. 如果集合中没有与该文件的唯一索引匹配的现有文件,则应将该新文件插入到集合中。

However, if there IS already a document in the collection with that unique index, it should be updated with the fields of the new document. 但是,如果集合中已经存在具有该唯一索引的文档,则应使用新文档的字段对其进行更新。 Any fields that are NOT present in the new document should be left untouched. 新文档中不存在的任何字段均应保持不变。

This is what I have currently which is working for inserting (but NOT for updating). 这是我目前正在处理的内容(但不适用于更新)。

const mongojs = require('mongojs');
const db = mongojs('mongodb://username:password@address.mlab.com:37230/database');

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

I understand this is wrong and it currently gives this error: 我了解这是错误的,并且当前会出现此错误:

E11000 duplicate key error index: database.items.$upc_1 dup key: E11000重复键错误索引:database.items。$ upc_1 dup键:

What is the proper query for this? 对此的正确查询是什么?

You can try using mongodb bulkWrite api: 您可以尝试使用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 });

I don't believe that you can update an entire array of documents at the same time. 我不认为您可以同时更新整个文档阵列。 Therefore, you would have to update each item in the array individually. 因此,您将必须分别更新阵列中的每个项目。

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

The {upsert: true} option will update if a record exists and insert if not. 如果有记录,则{upsert: true}选项将更新,如果不存在,则将插入。

What are you looking for is an upsert, not an insert. 您要寻找的是upsert,而不是insert。 It can be done by the following code: 可以通过以下代码完成:

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

Query will search for a document using the parameters of the query, if it finds, it will update the fields mentioned in . 查询将使用查询的参数搜索文档,如果找到,它将更新中提到的字段。 If it doesn't find, it will insert a new document with the fields and values of . 如果找不到,它将插入带有字段和值的新文档。

The last object (with multiple fields), contains a field to say if an upsert is desired and one called "multi" to say if an update on multiple documents is desired. 最后一个对象(具有多个字段)包含一个字段,用于说明是否需要更新,而一个称为“ multi”的字段用于说明是否需要对多个文档进行更新。

For example: 例如:

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

This will search for a document with the name "item1" and set its price to 20. If it doesn't find, it will create a new one with price 20. 这将搜索名称为“ item1”的文档,并将其价格设置为20。如果找不到,它将创建一个价格为20的新文档。

One thing to be noticed though is: 但是要注意的一件事是:

If you don't use the tag $set on the fields, it will substitute the whole document. 如果您不在字段上使用标签$ set,它将代替整个文档。

Supposing you have a document like this: 假设您有一个像这样的文档:

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

If you run the following two queries: 如果运行以下两个查询:

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

and

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

it will yeld different results: 它将产生不同的结果:

First one: 第一:

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

Second one: 第二个:

{_id:"1234",price:20}

If you don't call $set , it will change the whole document. 如果不调用$set ,它将更改整个文档。

More information on the manual: 有关手册的更多信息:

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

Hope my answer was helpful 希望我的回答有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM