Gui*_*age 31 mongoose mongodb node.js
对于我的项目,我想为组织组保留一份mongoose文档,如下所示:
var groupSchema = Schema({
name : { type : String },
org : { type : Schema.Types.ObjectId, ref : 'Organization' },
...
users : [{
uid : { type : Schema.Types.ObjectId, ref : 'User' },
...
}]
});
Run Code Online (Sandbox Code Playgroud)
我想阻止同一个用户在同一组中两次.为此,我需要强制users.uid在users数组中是唯一的.我尝试为uid说明'unique:true',但这不起作用.有没有办法用mongoose或mongoDB执行此操作而无需额外查询或拆分架构?
编辑:我将uid的先前值更改为uid:{type:Schema.Types.ObjectId,ref:'User',index:{unique:true,dropDups:true}}但是这似乎仍然不起作用.
编辑:假设没有简单的方法来实现这一点,我添加了一个额外的查询检查用户是否已经在组中.在我看来,这是最简单的方法.
Joh*_*yHK 82
在一个阵列场唯一索引强制执行相同的值不能出现在一个以上的阵列文档的集合中,但并不妨碍在单个文档的阵列多次出现相同的值.因此,您需要确保在向阵列添加元素时的唯一性.
$addToSet
仅当值尚未存在时,才使用运算符向数组添加值.
Group.update({name: 'admin'}, {$addToSet: {users: userOid}}, ...
Run Code Online (Sandbox Code Playgroud)
但是,如果users
数组包含具有多个属性的对象,并且您希望确保其中一个属性的唯一性(uid
在本例中),则需要采用另一种方法:
var user = { uid: userOid, ... };
Group.update(
{name: 'admin', 'users.uid': {$ne: user.uid}},
{$push: {users: user}},
function(err, numAffected) { ... });
Run Code Online (Sandbox Code Playgroud)
这样做的$push
唯一条件是,只有user.uid
在uid
任何元素的字段中不存在时才会发生更新users
.所以它模仿$addToSet
行为,但仅仅是uid
.
好吧,这可能是个老问题,但是对于 mongoose > v4.1,您可以使用$addToSet
运算符。
$addToSet 运算符将一个值添加到数组中,除非该值已经存在,在这种情况下 $addToSet 对该数组没有任何作用。
例子:
MyModal.update(
{ _id: 1 },
{ $addToSet: {letters: [ "c", "d" ] } }
)
Run Code Online (Sandbox Code Playgroud)