I am wondering how you would do a query where array._id != 'someid'.
Here is an example of why I would need to do this. A user wants to update their account email address. I need these to be unique as they use this to login. When they update the account I need to make sure the new email doesn't exist on another account, but don't give an error if it exists on their account already (they didn't change their email, just something else in their profile).
Below is the code I have tried using. It doesn't give any errors, but it always returns a count of 0 so an error is never created even if it should.
Schemas.Client.count({ _id: client._id, 'customers.email': email, 'customers._id': { $ne: customerID } }, function (err, count) {
if (err) { return next(err); }
if (count) {
// it exists
}
});
I'm guessing it should use either $ne, or $not, but I can't find any examples for this online with an ObjectId.
Example client data:
{
_id: ObjectId,
customers: [{
_id: ObjectId,
email: String
}]
}
I was able to do this using aggregate.
Why this didn't work the way I had it: When looking for $ne: customerID it will never return a result because that _id does in fact exist. It can't combine cutomers.email and customers._id the way I wanted it to.
Here is how it looks:
Schemas.Client.aggregate([
{ $match: { _id: client._id } },
{ $unwind: '$customers' },
{ $match: {
'customers._id': { $ne: customerID },
'customers.email': req.body.email
}},
{ $group: {
_id: '$_id',
customers: { $push: '$customers' }
}}
], function (err, results) {
if (err) { return next(err); }
if (results.length && results[0].customers && results[0].customers.length) {
// exists
}
});
);
With your existing query, the customers.email and customers._id parts of your query are evaluated over all elements of customers as a group, so it won't match a doc that has any element with customerID, regardless of its email. However, you can use $elemMatch to change this behavior so the two parts operate in tandem on each element at a time:
Schemas.Client.count({
_id: client._id,
customers: { $elemMatch: { email: email, _id: { $ne: customerID } } }
}, function (err, count) {
if (err) { return next(err); }
if (count) {
// it exists
}
});