如何停止在 mongodb 集合中插入重复文档
Posted
技术标签:
【中文标题】如何停止在 mongodb 集合中插入重复文档【英文标题】:How to stop insertion of Duplicate documents in a mongodb collection 【发布时间】:2014-07-30 03:40:11 【问题描述】:让我们有一个包含三个文档的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'
如何阻止这种重复。应该对哪个字段进行索引或任何其他方法?
【问题讨论】:
Mongodb avoid duplicate entries 的可能重复项 @John Petrone :在这里,我们不能对特定字段进行索引,因为字段的值是重复的。 unique:true 会产生问题。 使用复合索引docs.mongodb.org/manual/tutorial/create-a-compound-index 【参考方案1】:您要查找的是AddToSet
,而不是Push
或Insert
。
使用 Upsert
标志似乎对我不起作用。
即:var updateSet = Builders<T>.Update.AddToSet(collectionField, value);
请注意,AddToSet
似乎在进行值比较。
【讨论】:
【参考方案2】:也许这比其他方式慢一点,但它也有效。它可以在循环中使用:
db.collection.replaceOne(query, data, upsert: true)
查询可能是这样的:
_id: '5f915390950f276680720b57'
https://docs.mongodb.com/manual/reference/method/db.collection.replaceOne
【讨论】:
【参考方案3】:您应该在唯一标识 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/
【讨论】:
@Roberto ensureIndex 如果索引不存在则创建索引 哦,你是对的@Azmisov,但从 3.0 开始实际上已弃用 ensureIndex,现在它是 createIndex 的(已弃用)别名,因为创建此答案时不存在 3.0 我正在删除我的downvote :) (在编辑答案之前,它不允许我撤消我的 downvote,让我们希望 John Petrone 将其添加为更新...【参考方案4】:已根据上述答案进行了更新。
请使用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
。
【讨论】:
为什么应该首选这些选项?请详细说明你的答案。 据我所知,对于update
,它只是重新设计了响应对象。【参考方案5】:
不要使用插入。
使用update with upsert=true
。 Update 将查找与您的查询匹配的文档,然后它将修改您想要的字段,然后,如果没有文档与您的查询匹配,您可以告诉它 upsert:True 如果您想插入。
db.collection.update(
<query>,
<update>,
upsert: <boolean>,
multi: <boolean>,
writeConcern: <document>
)
因此,对于您的示例,您可以使用如下内容:
db.collection.update(doc, doc, upsert:true)
【讨论】:
请注意,如果您希望为第一次使用准备文档,则 upsert 可能很危险,因为它会很高兴地清除存储在那里的所有内容,以支持 upsert 值。 John P. 提出的模式是避免重复记录的更好的通用答案,尽管对于复合键将包含所有现有文档字段的简单情况,这两种方法都足够了。如果您考虑为记录添加非常常见的“创建时间”,您可以看到这在许多一般情况下是如何分解的...... 我恳请大家也参考 John Petrone 的回答!!以上是关于如何停止在 mongodb 集合中插入重复文档的主要内容,如果未能解决你的问题,请参考以下文章