Muirik
Muirik

Reputation: 6289

Using $or and $ne Operators Together in MongoDB Query

I am trying to run a MongoDB query to return all documents that don't match one value OR another. After consulting the documentation, I see this example:

{ $or: [ { quantity: { $lt: 20 } }, { price: 10 } ] }

So this is what I tried:

{ $or:  [ { paymentType: { $ne: "full" } }, { $ne: "partial" } ] }

This results in an error:

'unknown top level operator: $ne'

I also tried this:

{ $or:  [ { paymentType: { $ne: "full" } }, { paymentType: { $ne: "partial" }} ] }

... but this simply returns all documents, with no filtering done on the "paymentType" property.

What's the correct syntax here?

Upvotes: 2

Views: 2521

Answers (4)

Durvesh Parmar
Durvesh Parmar

Reputation: 15

As per the plain english understanding, you should use

{ $nor:  [ { paymentType: "full" }, { paymentType:  "partial"} ] }

This is the modification to @Muirik's answer as it didn't work for me as you are already using $nor. Thus, you should not use $ne inside.

Thanks.

Upvotes: 0

Akrion
Akrion

Reputation: 18525

If you need to find all documents which do not match those two values only why don't you simply change the $or to $and? Easiest and shortest is to use the $nin as already suggested but not sure why complicate it with $nor/$or etc.

{ $and:  [ { paymentType: { $ne: "full" } }, { paymentType: { $ne: "partial" }} ] }

will select all documents that don't match either of these values. It reads and understands much easier then the double negation you end up with $nor no?

It says give me all paymentTypes which are not full and not partial. Same if you use the $nin.

Upvotes: 0

Muirik
Muirik

Reputation: 6289

So, thanks to a commenter for pointing out that I could either use $nin or $and but not $or. Another option, which I find the most intuitive in this particular case, is the $nor operator, like so:

{ $nor:  [ { paymentType: { $ne: "full" } }, { paymentType: { $ne: "partial" }} ] }

This will return all documents that don't match either of these values.

Upvotes: 1

Mạnh Quyết Nguyễn
Mạnh Quyết Nguyễn

Reputation: 18235

Your third version of code syntax is correct.

But the logic seems wrong.

Your query translated to:

paymentType != full or paymentType != partial

This actually always hold true, (since one paymentType value cannot be full and partial at the same time.)

Update

To clarify, what I'm trying to query -- in plain English -- is to return all results where "paymentType" is not "full" or "partial".

In this case you should use $and instead. or $nin is also good.

Remember this law:

not (p or q) <=> (not p) and (not q)

Upvotes: 2

Related Questions