0

I have multiple conditions for the query in my controller that I need path if exists.

condition 1 :

{ tags: mongoose.Types.ObjectId(req.params.tagId)}

condition 2:

{ reportedBy: { '$ne': req.user._id }} // if this video object reported dont show

condition 3:

{ owner: { '$ne': userblocks } } // userblocks is a array of objectIds

so this is my $match filter:

{
 '$match':
   _.isString(req.params.tagId) ?
   { tags: mongoose.Types.ObjectId(req.params.tagId), 
   reportedBy:{ '$ne': req.user._id}, owner: { '$ne': userblocks}}:
   { reportedBy:{ '$ne': req.user._id},owner: {'$ne': userblocks}}
},

I used ... spread operator if tagId passed to params.this condition works for tagId but other conditions are not working.

with @Anthony Winzlet hint I tried to :

{reportedBy:{ '$ne': mongoose.Types.ObjectId(req.user._id)},owner: {'$ne': userblocks}} 

and userblocks is a list of objects, I checked the type of them and they are objects too.so no need to cast them to objectIds.

Babak Abadkheir
  • 2,222
  • 1
  • 19
  • 46
  • You need to cast your other id to mongoose objectId. Just you did with the `tagId` – Ashh Nov 18 '18 at 09:01
  • @AnthonyWinzlet in my user blocks all of them are objects not string. let userblocks = [...req.user.blockedUser, ...req.user.blockedBy].map(blocks=>mongoose.Types.ObjectId(blocks)); – Babak Abadkheir Nov 18 '18 at 09:08
  • @AnthonyWinzlet and I tried this to: {reportedBy:{ '$ne': mongoose.Types.ObjectId(req.user._id)},owner: {'$ne': userblocks}} – Babak Abadkheir Nov 18 '18 at 09:13

1 Answers1

1

Try something like this:

let $match = {
   reportedBy: { '$ne': mongoose.Types.ObjectId(req.user._id) },
   owner: { '$nin': userblocks } // $nin when comparing against array of object ids
},

if(_.isString(req.params.tagId)) {
   $match.tags = mongoose.Types.ObjectId(req.params.tagId)
}

Then just use $match in your aggregation pipeline or as part of whatever else parts of the pipeline you would have.

Things to note:

  • When comparing to _id mongoose.Types.ObjectId function should be used.
  • When comparing against an array $in or $nin are usually what you would want to use.
  • It seems in your _.isSting check logic you had reportedBy and owner in both scenarios so it seems to me some refactoring would not hurt.
Akrion
  • 18,117
  • 1
  • 34
  • 54
  • owner: {'$nin': userblocks} this works fine .but this is not working: reportedBy:{ '$ne': mongoose.Types.ObjectId(req.user._id)} – Babak Abadkheir Nov 18 '18 at 09:56