Reputation: 1867
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
).
Upvotes: 2
Views: 1362
Reputation: 1867
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:
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});
User schema:
var User = new Schema({
arrayType1 : {
type: [ArraySchema]
},
arrayType2 : {
type: [ArraySchema]
},
arrayType3 : {
type: [ArraySchema]
}
//More specifications for 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:
user.arrayType1.addToSet({user_id : user2._id, event_id : event._id});
user.save(function(err, result) {
//Callback logic.
};
Where user2
and event
are defined earlier in the code and saved to the db. Alternatively I could use Mongoose's update function as such:
User.update({_id : user._id}, {
$addToSet : {
arrayType1 : {
user_id : user2._id,
event_id : event._id
}
}
}, function(err) {
//Callback logic.
}
);
Upvotes: 1