首页 文章

Mongoose嵌套对象数组中的唯一值

提问于
浏览
20

对于我的项目,我想为组织组保留一份mongoose文档,如下所示:

var groupSchema = Schema({
  name : { type : String },
  org : { type : Schema.Types.ObjectId, ref : 'Organization' },
  ...
  users : [{
    uid : { type : Schema.Types.ObjectId, ref : 'User' },
    ...
  }]
});

我想阻止同一个用户在同一组中两次 . 为此,我需要强制users.uid在users数组中是唯一的 . 我尝试为uid说'unique:true',但那不起作用 . 有没有办法用mongoose或mongoDB执行此操作而无需额外查询或拆分架构?

编辑:我将uid的先前值更改为uid:{type:Schema.Types.ObjectId,ref:'User',index:{unique:true,dropDups:true}}但是这似乎仍然不起作用 .

编辑:假设没有简单的方法来实现这一点,我添加了一个额外的查询检查用户是否已经在组中 . 这在我看来是最简单的方法 .

2 回答

  • 64

    数组字段上的唯一索引强制相同的值不能出现在集合中多个文档的数组中,但不会出现在数组中 . 因此,您需要在向阵列添加元素时确保唯一性 .

    仅当值尚不存在时,才使用$addToSet运算符向数组添加值 .

    Group.update({name: 'admin'}, {$addToSet: {users: userOid}}, ...
    

    但是,如果 users 数组包含具有多个属性的对象,并且您希望确保其中一个属性的唯一性(在本例中为 uid ),则需要采用另一种方法:

    var user = { uid: userOid, ... };
    Group.update(
        {name: 'admin', 'users.uid': {$ne: user.uid}}, 
        {$push: {users: user}},
        function(err, numAffected) { ... });
    

    这样做只会在 $push 的任何元素的 uid 字段中不存在 user.uid 时才发生 $push 更新 . 所以它模仿了 $addToSet 行为,但仅仅是 uid .

  • 2

    那么这可能是一个老问题但是对于mongoose> v4.1,你可以使用 $addToSet 运算符 .

    $ addToSet运算符向数组添加一个值,除非该值已经存在,在这种情况下$ addToSet对该数组不执行任何操作 .

    例:

    MyModal.update(
       { _id: 1 },
       { $addToSet: {letters: [ "c", "d" ] } }
    )
    

相关问题