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

sha*_*ank 40 database mongodb nosql mongodb-query

让我们有一个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' }
Run Code Online (Sandbox Code Playgroud)

我们有一份文件,

 doc = { user: 'B', title: 'Chemistry', Bank:'Bank_A' }
Run Code Online (Sandbox Code Playgroud)

如果我们使用

 db.collection.insert(doc) 
Run Code Online (Sandbox Code Playgroud)

在这里,这个重复的文档将插入数据库中.

 { _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' }
Run Code Online (Sandbox Code Playgroud)

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

小智 49

不要使用插入物.

使用更新upsert=true.更新将查找与您的查询匹配的文档,然后它将修改您想要的字段,然后,您可以告诉它upsert:如果您想在没有文档与您的查询匹配时插入,则为True.

db.collection.update(
   <query>,
   <update>,
  {
    upsert: <boolean>,
     multi: <boolean>,
    writeConcern: <document>
   }
  )
Run Code Online (Sandbox Code Playgroud)

所以,对于你的例子,你可以使用这样的东西:

db.collection.update(doc, doc, {upsert:true})
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果您希望首次使用文档,那么upsert会很危险,因为它会很好地消除存储在那里的任何内容,有利于upserted值.John P.提出的模式是避免重复记录的更好的一般答案,尽管任何一种方法都适用于复合键包含所有现有文档字段的简单情况.如果您考虑为记录添加"创建时间"非常常见,您可以看到这对于许多一般情况如何分解...... (3认同)

Joh*_*one 32

您应该在唯一标识MongoDB集合中的文档的字段集上使用复合索引.例如,如果您确定user,title和Bank的组合是您的唯一键,您将发出以下命令:

db.collection.createIndex( { user: 1, title: 1, Bank: 1 }, {unique:true} )
Run Code Online (Sandbox Code Playgroud)

请注意,应在删除以前存储的重复项后执行此操作.

http://docs.mongodb.org/manual/tutorial/create-a-compound-index/

http://docs.mongodb.org/manual/tutorial/create-a-unique-index/


Cre*_*eem 5

它已从上述答案中更新.

请用db.collection.updateOne()而不是db.collection.update().而且db.collection.createIndexes()而不是db.collection.ensureIndex()

更新:方法update()和ensureIndex()已从mongodb 2.*中弃用,您可以在mongo中查看更多详细信息,路径是./mongodb/lib/collection.js.对于update(),推荐的方法是updateOne, updateMany, or bulkWrite.对于ensureIndex(),推荐的方法是createIndexes.

  • 为什么应该优先选择这些选项?请详细说明您的答案。 (2认同)