我有一个带有唯一索引的MongoDB集合。 我正在尝试将一组文档插入或更新到该集合中。
如果集合中没有与文档的唯一索引匹配的现有文档,则应将该新文档插入集合中。
但是,如果集合中已存在具有该唯一索引的文档,则应使用新文档的字段进行更新。任何不存在于新文档中的字段都应保持不变。
这是我目前正在进行插入的工作(但不用于更新)。
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);
}
})
我明白这是错误的,它目前会出现此错误:
E11000重复键错误索引:database.items。$ upc_1 dup key:
对此有什么正确的查询?
答案 0 :(得分:3)
您可以尝试使用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 });
答案 1 :(得分:2)
我不相信您可以同时更新整个文档数组。因此,您必须单独更新阵列中的每个项目。
items.forEach((item) => {
db.items.update({_id: item._id}, item, {upsert: true}, (err, task) => {
if (err) {
console.log(err);
}
});
}
如果记录存在,{upsert: true}
选项将更新,如果没有,则更新。
答案 2 :(得分: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})
这将搜索名为“item1”的文档,并将其价格设置为20.如果找不到,则会创建一个价格为20的新文档。
有一点需要注意的是:
如果您不在字段上使用标记$ set,它将替换整个文档。
假设你有这样的文件:
{_id:"1234",name:"item1",price:10}
如果您运行以下两个查询:
db.items.update({name:"item1"},{$set:{price:20}},...)
和
db.items.update({name:"item1"},{price:20},...)
它会产生不同的结果:
第一个:
{_id:"1234",name:"item1",price:20}
第二个:
{_id:"1234",price:20}
如果您不致电$set
,则会更改整个文档。
有关手册的更多信息:
https://docs.mongodb.com/manual/reference/method/db.collection.update/
希望我的回答很有帮助