[SERVER-10708] negation of query expressions using "$not" Created: 07/Sep/13  Updated: 06/Dec/22  Resolved: 09/Feb/21

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.5.1, 2.6.3
Fix Version/s: None

Type: Improvement Priority: Minor - P4
Reporter: Jared Rosoff Assignee: Backlog - Query Optimization
Resolution: Duplicate Votes: 1
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates SERVER-1454 Use $not as a top-level logical op Backlog
is duplicated by SERVER-21936 support $not as top level operator Closed
Assigned Teams:
Query Optimization
Participants:

 Description   

It is possible to negate arbitrary expression using the "$nor" expression. This ticket only tracks extending the syntax to allow negating expressions with "$not" as well.

Original description:
$not currently (<=2.5.1) only supports negating equality operators. so i can do { field: { $not : { [$eq,$gt,$lt,...] } }

but there is no way to negate an entire expression.

some example negated expressions (that don't work now):

Example expression Logically equivalent to
{ $not: {a: 1} } {a: {$ne: 1}}
{ $not: {a: 1, b: 2}

{$or: [ {a: {$ne: 1}}, {b: {$ne: 2}} ]}
{ $not: {$and: [ {a: 1}, {b: 2}] } {$or: [ {a: {$ne: 1}}, {b: {$ne: 2}} ]}
{ $not: {$or: [ {a:1}, {b:2} ]} {$and: [ {a: {$ne: 1}}, {b: {$ne: 2}} ]}
{ a: 1, $not: {b: 2}} {a: 1, b: {$ne: 2}}


 Comments   
Comment by Charlie Swanson [ 09/Feb/21 ]

Hi all. I've found SERVER-1454 which I believe is a duplicate of this request, so I am closing it as such. Please leave a comment if you disagree!

Comment by J Rassi [ 17/Dec/15 ]

Note that the $nor operator (available since version 1.4) can be used to negate an expression.

> db.version()
3.2.0
> db.foo.insert({a:1})
WriteResult({ "nInserted" : 1 })
> db.foo.insert({a:2})
WriteResult({ "nInserted" : 1 })
> db.foo.find({$not:{a:1}})
Error: error: {
	"waitedMS" : NumberLong(0),
	"ok" : 0,
	"errmsg" : "unknown top level operator: $not",
	"code" : 2
}
> db.foo.find({$nor:[{a:1}]})
{ "_id" : ObjectId("567329f84639a53bdbc74fe0"), "a" : 2 }

Changing the type of this ticket to "Improvement", to track the work required to extend the syntax for $not.

Comment by Thomas Rueckstiess [ 19/Aug/14 ]

Still not working on 2.6.3.

Comment by Jared Rosoff [ 07/Sep/13 ]

Does not work.

> db.version() 
2.5.2
> db.foo.find({$not:{a:1}})
error: {
	"$err" : "bad query: BadValue unknown top level operator: $not",
	"code" : 16810
}

Comment by Eliot Horowitz (Inactive) [ 07/Sep/13 ]

These should work in 2.5.2, can you verify?

Generated at Thu Feb 08 03:23:51 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.