[SERVER-4973] $not should return error if used as a top-level key in query document Created: 15/Feb/12  Updated: 11/Jul/16  Resolved: 12/Nov/13

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.0.2
Fix Version/s: 2.5.3

Type: Bug Priority: Minor - P4
Reporter: Robert Stam Assignee: Unassigned
Resolution: Done Votes: 1
Labels: query_triage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Depends
depends on SERVER-6650 should matcher prevent use of $ prefi... Closed
Related
is related to SERVER-7391 Parse bson queries into new MatchExpr... Closed
Operating System: ALL
Participants:

 Description   

Given a small collection with these values:

> db.test.find()
{ "_id" : ObjectId("4f3ade128e2fc474150d9afd"), "x" : 1, "y" : 2 }
{ "_id" : ObjectId("4f3ade168e2fc474150d9afe"), "x" : 3, "y" : 4 }
{ "_id" : ObjectId("4f3adec28e2fc474150d9aff"), "x" : 5, "y" : 6 }
>

This simple query gives the obvious results:

> db.test.find({x:1,y:2})
{ "_id" : ObjectId("4f3ade128e2fc474150d9afd"), "x" : 1, "y" : 2 }
>

But why doesn't this query using $not work?

> db.test.find({$not:{x:1,y:2}})
>

I expected it to simply return all the documents that didn't match the first time.

If this usage of $not is not supported then an error should be returned.



 Comments   
Comment by David Storch [ 12/Nov/13 ]

This is indeed invalid use of $not because, as specified by the documentation, the argument to $not must be an "operator expression". Operator expressions, in this setting, are things like

{$gt: 4}, {$exists: true}, etc.

That is, an operator expression is a document whose only key is a "$"-prefixed query operator.

Validation for $not has been added, so now your example will give an error. Here's what I get running against development release 2.5.3:

> c = db.c
test.c
> c.drop()
true
> c.save({x: 1, y: 2})
> c.save({x: 3, y: 4})
> c.save({x: 5, y: 6})
> c.find()
{ "_id" : ObjectId("52827adca4682f073415c108"), "x" : 1, "y" : 2 }
{ "_id" : ObjectId("52827ae3a4682f073415c109"), "x" : 3, "y" : 4 }
{ "_id" : ObjectId("52827af2a4682f073415c10a"), "x" : 5, "y" : 6 }
> db.test.find({$not: {x:1, y:1}})
error: {
	"$err" : "bad query: BadValue unknown top level operator: $not",
	"code" : 16810
}
> db.test.find({x: {$not: 1}})
error: { "$err" : "invalid use of $not", "code" : 13041 }

Given that the error checking has been tightened, I'm going to close this issue as fixed.

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