I am trying to create an index on two fields of a schema that are to be unique and sparse in MongoDB using Mongoose as follows:
var ArraySchema = new Schema ({
user_id: {type: mongoose.Schema.Types.ObjectId, ref:'User'},
event_id: {type: mongoose.Schema.Types.ObjectId, ref:'Event'}
}, {_id:false});
ListSchema.index({user_id:1, event_id:1}, {sparse:true, unique:true});
Which is then used in an array in the User schema as such:
var User = new Schema({
arrayType1 : {
type: [ArraySchema]
},
arrayType2 : {
type: [ArraySchema]
},
arrayType3 : {
type: [ArraySchema]
}
//More specifications for user schema...
});
However, when trying to save multiple users without the array field, errors are thrown for duplicate fields. The error in Mocha looks similar to this: array.event_id_1 dup key {null, null}. An example of a segment of code that would throw this error is as follows:
var user1, user2;
user1 = new User({
username : 'username1',
password : 'password'
});
user2 = new User({
username : 'username2',
password : 'password'
});
user1.save(function() {
user2.save();
});
Here is my reasoning behind making the the fields of ArraySchema unique and sparse: If the array field is specifed, I do not want the array to contain duplicate objects; however, the array field is not required, so there will be many Users that have null for this field. Obviously I cannot use field-level indices since there are multiple fields that would need an index (arrayType1, arrayType2, arrayType3).
It appears that doing this sort of thing is not supported, at least at this time. The alternative would be to create a compound index on these fields then whenever adding a new element to the field use
user.arrayType1.addToSet(). Here is an example of how this would work:ArraySchema:
User schema:
Then I could declare new users as usual (as I did in the question); however, when I want to add a new element to
arrayType1, for example, I would use the following line of code to add to new element only if it is not already there:Where
user2andeventare defined earlier in the code and saved to the db. Alternatively I could use Mongoose's update function as such: