Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
946 views
in Technique[技术] by (71.8m points)

node.js - Mongoose Unique values in nested array of objects

For my project, I want to keep a mongoose document for groups of organizations, like this:

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

I want to prevent the same user from being in the same group twice. To do this, I need to force users.uid to be unique in the users array. I tried stating 'unique : true' for uid, but that didn't work. Is there a way to do this with mongoose or mongoDB without extra queries or splitting the schema?

Edit: I changed the previous value of uid to uid : { type : Schema.Types.ObjectId, ref : 'User', index: {unique: true, dropDups: true} } But this still doesn't seem to work.

Edit: Assuming there is no simple way to achieve this, I added an extra query checking if the user is already in the group. This seems to me the simplest way.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A unique index on an array field enforces that the same value cannot appear in the arrays of more than one document in the collection, but doesn't prevent the same value from appearing more than once in a single document's array. So you need to ensure uniqueness as you add elements to the array instead.

Use the $addToSet operator to add a value to an array only if the value is not already present.

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

However, if the users array contains objects with multiple properties and you want to ensure uniqueness over just one of them (uid in this case), then you need to take another approach:

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

What that does is qualify the $push update to only occur if user.uid doesn't already exist in the uid field of any of the elements of users. So it mimics $addToSet behavior, but for just uid.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...