Jef*_*ner 3 atomic mongoose mongodb
在 Mongoose 中,我正在寻求以原子方式执行Model.FindOne-Or-Insert()与当前可用的类似功能和签名的方法,Model.FindOneAndUpdate()除非实例存在(即匹配filter)然后不使用提供的更新object但原样返回找到的实例,如果不存在(即不匹配) with 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)
}
Run Code Online (Sandbox Code Playgroud)
建议?谢谢
您可以$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 }
)
Run Code Online (Sandbox Code Playgroud)
请注意,您还应该为包含在您的字段中的字段创建唯一索引filter,然后处理重复错误的可能性。有关原因,请参阅此帖子的详细信息。
| 归档时间: |
|
| 查看次数: |
1672 次 |
| 最近记录: |