【问题标题】:Mongoose: atomic FindOne-Or-Insert(), do not update existing instance if foundMongoose:原子 FindOne-Or-Insert(),如果找到不更新现有实例
【发布时间】:2019-04-12 04:30:00
【问题描述】:

在 Mongoose 中,我正在寻求以原子方式执行 Model.FindOne-Or-Insert(),与当前可用的 Model.FindOneAndUpdate() 类似的功能和签名,除非存在实例(即匹配 filter)然后 不要使用提供的更新object 但返回找到的实例原样,如果不存在(即与filter 不匹配)则插入object 并返回新实例。

我找不到使用Model.FindOneAndUpdate() 不执行更新现有实例的方法,方法是尝试对其options 的差异并且不向object 提供如果实例存在则不希望更新的字段。

所以,我当前的非原子解决方法是Model.FindOne(),如果找不到,则执行Document.save()

const Foo = DB.model('foo', FooSchema)

async function findOneAndUpdateFoo(jsonFoo, next) {

  const filter = {
    deletedAt: null
  }
  if (jsonFoo.dsAccountId) {
    filter.dsAccountId = jsonFoo.dsAccountId
  }
  if (jsonIntegration.dsUserId) {
    filter.dsUserId = jsonIntegration.dsUserId
  }
  if (jsonFoo.providerId) {
    filter.providerId = jsonFoo.providerId
  }

  const fooDoc = {
    name: jsonFoo.name,
    dsAccountId: jsonFoo.dsAccountId,
    dsUserId: jsonFoo.dsUserId,
    providerId: jsonFoo.providerId,
    providerName: jsonFoo.providerName,

    // Most of these fields could be empty
    accessToken: jsonFoo.accessToken,
    refreshToken: jsonFoo.refreshToken,
    scope: jsonFoo.scope,
    tokenType: jsonFoo.tokenType,
    expiresAt: jsonFoo.expiresAt
  }

  return await Foo.findOneAndUpdate(
    filter, // find a document with that filter
    fooDoc, // document to insert when nothing was found
    { upsert: true, new: true, runValidators: true } // options
  )
    .catch(next)
}

建议?谢谢

【问题讨论】:

  • @JohnnyHK 感谢您的及时回复。我已经使用 Model.FindOneAndUpdate() 更新了我的问题显示代码。我现在正在查看您的建议。

标签: mongodb mongoose atomic


【解决方案1】:

您可以在更新参数中使用$setOnInsert,以便它仅适用于插入情况;在文档已经存在的情况下,更新变为无操作:

return await Foo.findOneAndUpdate(
  filter,                 // find a document with that filter
  {$setOnInsert: fooDoc}, // document to insert when nothing was found
  { upsert: true, new: true, runValidators: true }
)

请注意,您还应该为 filter 中包含的字段创建唯一索引,然后处理出现重复错误的可能性。详情请参阅this post

【讨论】:

  • 感谢您的建议! $setOnInsert 成功了!
  • @JohnnyHK is upsert: true required?
  • 在我的例子中索引也是objectId。
猜你喜欢
  • 2013-04-27
  • 2021-02-12
  • 2017-03-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多