如何停止在mongodb集合中插入重复文档

时间:2014-06-09 14:56:51

标签: mongodb mongodb-query database nosql

我们有一个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' }

如何停止此重复。应该在哪个字段上编制索引或采用其他方法?

4 个答案:

答案 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