node.js - Mongoose 嵌套对象数组中的唯一值

标签 node.js mongodb mongoose

对于我的项目,我想为组织组保留一个 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 声明“唯一:真”,但这没有用。有没有办法用 mongoose 或 mongoDB 做到这一点,而无需额外的查询或拆分架构?

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

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

最佳答案

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

使用 $addToSet运算符仅在值不存在时才向数组添加值。

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

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

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

这样做是限定 $push 更新仅在 user.uiduid 字段中不存在时发生users 的任何元素。所以它模仿了 $addToSet 的行为,但只适用于 uid

关于node.js - Mongoose 嵌套对象数组中的唯一值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15921700/

相关文章:

node.js - webpack开发服务器: TypeError: The header content contains invalid characters

javascript - 填充已获取的文档。有可能吗?如果可以,怎么办?

Mongoose .js : remove collection or DB

javascript - 如果绑定(bind)在 KnockoutJS 中不起作用,则为无容器

node.js - 如何在 Synology DS218J 中使用 Angular

javascript - Nodejs Sequelize 如何获取最后一个插入ID

Mongodb 查询选择执行

java - Mongodb 聚合(Java/Spring)查询以获取最后一个子元素

MongoDB:检查嵌套键值对是否存在

Node.js + Mongoose/Mongo 和缩短的 _id 字段