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
user2
andevent
are defined earlier in the code and saved to the db. Alternatively I could use Mongoose's update function as such: