我们有一个MongoDB
集合,其中有三个文档..
db.collection.find()
{ _id:'...', user: 'A', title: 'Physics', Bank: 'Bank_A' }
{ _id:'...', user: 'A', title: 'Chemistry', Bank: 'Bank_B' }
{ _id:'...', user: 'B', title: 'Chemistry', Bank: 'Bank_A' }
我们有一份文件,
doc = { user: 'B', title: 'Chemistry', Bank:'Bank_A' }
如果我们使用
db.collection.insert(doc)
此处,此重复文档将插入数据库中。
{ _id:'...', user: 'A', title: 'Physics', Bank: 'Bank_A' }
{ _id:'...', user: 'A', title: 'Chemistry', Bank: 'Bank_B' }
{ _id:'...', user: 'B', title: 'Chemistry', Bank: 'Bank_A' }
{ _id:'...', user: 'B', title: 'Chemistry', Bank: 'Bank_A' }
如何停止此重复。应该在哪个字段上编制索引或采用其他方法?
答案 0 :(得分:49)
不要使用插入物。
使用update with upsert=true
。更新将查找与您的查询匹配的文档,然后它将修改您想要的字段,然后,您可以告诉它upsert:如果您想在没有文档与您的查询匹配时插入,则为True。
db.collection.update(
<query>,
<update>,
{
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
}
)
因此,对于您的示例,您可以使用以下内容:
db.collection.update(doc, doc, {upsert:true})
答案 1 :(得分:26)
您应该在唯一标识MongoDB集合中的文档的字段集上使用复合索引。例如,如果您确定user,title和Bank的组合是您的唯一键,您将发出以下命令:
db.collection.createIndex( { user: 1, title: 1, Bank: 1 }, {unique:true} )
请注意,应在删除以前存储的重复项后执行此操作。
http://docs.mongodb.org/manual/tutorial/create-a-compound-index/
http://docs.mongodb.org/manual/tutorial/create-a-unique-index/
答案 2 :(得分:5)
已根据上述答案进行了更新。
请使用db.collection.updateOne()
代替db.collection.update()
。
还有db.collection.createIndexes()
而不是db.collection.ensureIndex()
更新:
从mongodb 2. *中弃用了方法update()和ensureIndex(),您可以在mongo中查看更多详细信息,路径为./mongodb/lib/collection.js
。
对于update()
,建议的方法是updateOne, updateMany, or bulkWrite
。
对于ensureIndex()
,建议的方法是createIndexes
。
答案 3 :(得分:0)
也许这比其他方法要慢一些,但它也可以工作。它可以在循环内使用:
db.collection.replaceOne(query, data, {upsert: true})
查询可能类似于:
{ _id: '5f915390950f276680720b57' }
https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne