【发布时间】:2017-09-19 00:49:33
【问题描述】:
假设我有一个名为 Users 的集合中的文档如下所示:
{
name: 'vic', <-- unique index
ownedItems: ['paperclip-1252', 'stapler-1337']
}
ownedItems 是其他一些 Items 集合中唯一索引标识符的数组。现在,假设我想向ownedItems 数组添加一个元素,但我想强制执行以下规则:不能以导致存在多个包含相同项目的用户文档的方式更新用户的ownedItems 数组他们 ownItems 数组中的标识符。
也就是说,我要执行:
db.Users.updateOne(
{ name: 'vic'},
{ $set: {
ownedItems: [
'paperclip-1252',
'stapler-1337',
'notebook-42'
]
}
})
... 仅当没有其他用户文档具有包含“notebook-42”(或“paperclip-1252”或“stapler-1337”)的ownedItems 数组时才允许成功。
我可以做一个查询来检查,除了 'vic' 之外的任何用户是否拥有提议的ownedItems 数组中的任何项目,如下所示:
db.Users.find({
$and: [
{
ownedItems: {
$in: ['paperclip-1252', 'stapler-1337','notebook-42']
}
},
{
name: { $ne: 'vic' }
}
]
})
... 并且只有在没有返回结果时才继续更新。但是,在我得到那个答案和执行更新之间的时间里,谁说这个答案没有改变(例如,因为其他人将“notebook-42”插入到他们的 ownItems 中)?
如何以原子方式执行该查询,然后根据结果更新文档?虽然我已经使用 MongoDB CLI 语法对此进行了描述,但我宁愿使用 mongodb 包在 NodeJS 应用程序中实现此逻辑,以防万一。
【问题讨论】: