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 命令吗?我能找到的只有findOneAndUpdatereplaceOne 等东西,它们都支持可选的“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:如果文档不存在则创建,否则啥也不做的主要内容,如果未能解决你的问题,请参考以下文章

HIVE:如果存在则替换行中的字符串/模式,否则啥也不做

Python 列表添加字典,如果key值存在则啥也不做

如果您的 UIScrollView 已经处于该缩放级别,则 zoomToRect 啥也不做

PHP - 如果是这种情况,啥也不做

MKOverlayView 性能问题。啥也不做。但慢

如果从函数内部执行,带有“apply_async”的多处理池啥也不做