Mongo:如果文档不存在则创建,否则啥也不做
Posted
技术标签:
【中文标题】Mongo:如果文档不存在则创建,否则啥也不做【英文标题】:Mongo: create if document doesn't exist, otherwise do nothingMongo:如果文档不存在则创建,否则什么也不做 【发布时间】:2021-09-13 12:20:12 【问题描述】:我有一个 Mongo 集合,它有两个字段,比如说“name”和“randomString”。
我想为一个名称创建一个随机字符串,前提是它不存在。因此, name: "SomeName"
的第一个请求将导致保存,例如 name: "someName", randomString: "abc"
。第二个请求什么也不做。
这有 mongo 命令吗?我能找到的只有findOneAndUpdate
、replaceOne
等东西,它们都支持可选的“upsert”,但他们在匹配时的行为是更新,我希望匹配时的行为什么都不做。
我不是在寻找像 this question 这样的 if-then 解决方案,因为我遇到了竞争条件问题 - 我需要能够同时获取多个请求,而无需更新文档或使任何请求失败。
【问题讨论】:
这能回答你的问题吗? Find one or create with Mongoose name, randomString: 'abc'
不是有效的 JSON。您的输入是什么,您期望输出什么?
@raina77ow 不是真的,我正在尝试解决此答案无法解决的竞争条件
@WernfriedDomscheit 这是一个nodejs对象格式
【参考方案1】:
是的,有一个命令可以做到这一点,你可以使用 $addToSet 方法。 欲了解更多信息,请通过给定的链接:https://docs.mongodb.com/manual/reference/operator/update/addToSet/
PS:如果您对此问题仍有任何疑问,请随时进一步评论。
谢谢
【讨论】:
谢谢,但它不是一个数组,所以我不认为 addToSet 应用 嗨,这也适用于对象我已经尝试过并使用过这个【参考方案2】:您可以使用$exists
命令轻松检查randomString
字段,然后在聚合管道中使用$set 来更新该字段。
db.collection.updateMany("name":someName,"randomString":$exists: false,[$set:"randomString":"abcd"],upsert:true)
如果条件查询不匹配任何文档,则返回null
。
注意:聚合管道仅适用于 MongoDB 4.2 及更高版本的 updateMany()
。
【讨论】:
如果文档不存在,则不会创建新文档。 是的,但是现在它会一遍又一遍地创建一个新文档,因为它找不到与"randomString":$exists: false
匹配的东西
一遍又一遍地创造是什么意思?如果它没有找到任何文档,除了创建一个新文档之外它不会做任何事情。它取决于搜索查询“name:someName”,所以一旦更新了所有具有该名称的文档,就是这样。【参考方案3】:
这是我最后找到的解决方案:
CustomerRandomString.findOneAndUpdate(
name: "someName" ,
$setOnInsert: randomString: generateRandomString() ,
,
upsert: true ,
);
setOnInsert 运算符仅适用于创建新文档时,这正是我所需要的。
编辑:根据the docs,此解决方案需要在字段上使用unique index,以完全避免重复。
【讨论】:
以上是关于Mongo:如果文档不存在则创建,否则啥也不做的主要内容,如果未能解决你的问题,请参考以下文章