Reputation:
I have the below Mongoose function where I am trying to do a select WHERE email
= req.body.email
and referenceId
is not in an array.
referenceId
is a string array [String]
which has an array of object ID's.
const refereeSchema = new Schema({
firstName: {
type: String,
required: true
},
lastName: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
referenceId: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
}
],
token: {
type: String,
required: true
},
password: {
type: String
},
company: {
type: String,
required: true
},
role: {
type: String,
required: false
},
startedOn: Date,
endedOn: Date,
createdAt: Date,
updatedAt: Date
});
Referee.findOneAndUpdate({
email: req.body.email,
referenceId: {
'$ne': [new mongo.ObjectID(req.params.referenceId)]
}
}, {
$push: {
referenceId: new mongo.ObjectID(req.body.referenceId)
}
}, {
new: true
}, (err, doc) => {
if (err) {
res.status(401).send(err);
}
res.send(doc);
});
Each time I run the above it always matches and pushes the ObjectId even though it already existed before.
{ referenceId:
[ 5ba94232b492890982e7a417,
5ba94232b492890982e7a417,
5c20d8f907a55accd720c27f,
5c20d8f907a55accd720c27f,
5c20d8f907a55accd720c27f,
5c20d8f907a55accd720c27f,
5c20d8f907a55accd720c27f,
5c20d8f907a55accd720c27f ],
_id: 5c20e86d72d5c1ce20b961fa,
firstName: 'Richard',
lastName: 'Hendricks',
email: '[email protected]',
token: '319d9f5a-68e1-6f47-a9f1-7fbbf617a45c',
company: 'Pied Piper',
role: '',
__v: 0 }
Could someone please help me?
I'd like to do a check to see if the ObjectId is already in the array then DO NOTHING else push it.
Upvotes: 4
Views: 3045
Reputation: 1201
$push will just push data in array, you should use $addToSet
$addToSet only ensures that there are no duplicate items added to the set and does not affect existing duplicate elements. $addToSet does not guarantee a particular ordering of elements in the modified set
Referee.findOneAndUpdate({
email: req.body.email,
referenceId: {
'$ne': [new mongo.ObjectID(req.params.referenceId)]
}
}, {
$addToSet: {
referenceId: new mongo.ObjectID(req.body.referenceId)
}
}, {
new: true
}, (err, doc) => {
if (err) {
res.status(401).send(err);
}
res.send(doc);
});
more ever, you can use $elemMatch
or $nin
as find query, so that document itself doesnt return if id is in referenceId
$elemMatch :
referenceId: {
'$elemMatch': { '$ne': new mongo.ObjectID(req.params.referenceId) }
}
$nin:
referenceId: {
'$nin': [new mongo.ObjectID(req.params.referenceId)]
}
Upvotes: 5
Reputation: 36349
Consider using the $elemMatch operator in complement of $ne
. $ne
against the array itself will always return true in this case, because the array you're passing in the parameter is never going to equal the array in the document.
I haven't tested this, but something along these lines should work:
Referee.findOneAndUpdate({
email: req.body.email,
referenceId: {
'$elemMatch': { '$ne': new mongo.ObjectID(req.params.referenceId) }
}
}, {
$push: {
referenceId: new mongo.ObjectID(req.body.referenceId)
}
}, {
new: true
}, (err, doc) => {
if (err) {
res.status(401).send(err);
}
res.send(doc);
});
Also, you probably already know this but there are actually two ObjectId classes you might be importing, the one you want is mongoose.Types.ObjectId
Upvotes: 1