[DOCS-128] Document the behavior of $not applied to a subdocument containing multiple operators Created: 14/Feb/12  Updated: 30/Oct/23  Resolved: 16/Feb/12

Status: Closed
Project: Documentation
Component/s: Server
Affects Version/s: None
Fix Version/s: Server_Docs_20231030

Type: Improvement Priority: Major - P3
Reporter: Aaron Staple Assignee: Sam Kleinman (Inactive)
Resolution: Done Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
is related to SERVER-4965 $not appears to distribute incorrectl... Closed
Participants:
Days since reply: 12 years, 1 day ago

 Description   

There has been some confusion on this topic in the past, see SERVER-4965.



 Comments   
Comment by Aaron Staple [ 21/Feb/12 ]

Hi Sam - that all seems correct, thanks.

Comment by Sam Kleinman (Inactive) [ 21/Feb/12 ]

Aaron,

I've mad the following modification, that I want you to check. I think the above example is correct.

:operator:`$not` is a meta operator used to reverse the operation
of a standard operator. If a document does not match a query statement,
passing that query statement to the :operator:`$not` will return
that document. The operation of :operator:`$not` is consistent with
the behavior of other operators, but may yield unexpected results
with some data types, like arrays.
 
:operator:`$not` only affects *other operators*, and is unable to
check fields and documents independently. Use :operator:`$ne` to
test the contents of fields directly and :operator:`$nor` for
logical disjunctions.

My goal is to provide a framework for users to be able to intuit/test what the behavior of the operators will be, without outlining the variety of behaviors based on use case and situation. We can create specific bugs for odd behavior as we become aware of them, I just want to make sure the documentation is as good as it can be fore now.

Comment by Aaron Staple [ 18/Feb/12 ]

Hi Sam,

So the general policy is for $not to reverse the match. If I have a document containing

{a:[1,2]}

it will be matched by {$gt:1} so will not be matched by {$not:{$gt:1}}. The same rule for $not applies to the $ne operator. But the $ne operator behaves differently with arrays than other operators (like $gt). The query {a:{$ne:1}} will not match

{a:[1,2]}

so {a:{$not:

{ne:1}

}} will match

{a:[1,2]}

(in this case $not:$ne is equivalent to an equality check).

It's possible there are some operators or values (in particular null) for which $not doesn't produce the exact opposite matching behavior. We don't have a query language spec - it's basically been "the behavior is what the matching code implements."

Comment by Sam Kleinman (Inactive) [ 16/Feb/12 ]

it would be good the have some clarity on the exact impact of $not behaviors of the operators. If you could check that would be great.

Comment by Aaron Staple [ 16/Feb/12 ]

Also, I think right now $not:$gt is not exactly the same as $lte. If you have an array for example [ 1, 2 ]

I think $gt:1 will match and $lte:1 will match but $not:{$gt:1} will not match.

Can check more precisely on this if it's important.

Comment by Aaron Staple [ 16/Feb/12 ]

Sorry, it was a typo.

Comment by Sam Kleinman (Inactive) [ 16/Feb/12 ]

My understanding of SERVER-4965 is that

{ a: { $not:

{ $gt:0, $lt:5 }

} }

will yield: ( a <= 0 ) AND ( a => 5 )

Was that a typo on your part in the above example or is it doing something to the second operator that I've failed to comprehend.

Comment by Aaron Staple [ 16/Feb/12 ]

I think it might be helpful to explicitly mention the case that was causing confusion in SERVER-4965, which is that { a: { $not:

{ $gt:0, $lt:5 }

} } means roughly ( a <= 0 ) AND ( a > 5 ) not ( a <= 0 ) OR ( a > 5 ).

Comment by Sam Kleinman (Inactive) [ 16/Feb/12 ]

Just to clear on what I'm working on putting some more of this out in the open here.

Github botches the formatting of the new docs that I'm working on, but the file is here, <https://github.com/tychoish/mongodb-docs/blob/master/source/reference/operators.rst>, and the relevant section is below.

.. operator:: $not
 
   :operator:`$not` is a meta operator used to negate a standard
   operator. *It can only affect other operators*, and is unable to
   check fields and documents independently. Use :operator:`$ne` to
   test the contents of fields directly and :operator:`$nor` for
   logical disjunctions.
 
   Consider the following example of :operator:`$not`:
 
   .. code-block:: javascript
 
      db.collection.find( { field: { $not: { $type: 2 } } } );
 
   This query returns all documents in ``collection`` where ``field``
   is *not* a string, using the :operator:`$type` operator.
 
   .. note::
 
      The :operator:`$not` operator does not support operations with
      :operator:`$regex`.
 
      When using :operator:`$not`, pass all regular expressions using
      the native BSON type. For example, consider the following
      expression fragment  in Python, using the PyMongo driver:
 
      .. code-block:: python
 
        { "$not": re.compile("acme.*corp")}

I'm certainly open to feedback and suggestions.

Comment by Sam Kleinman (Inactive) [ 16/Feb/12 ]

Clarification to wiki, and new documentation will contain more clear documentation in the operator reference.

Will close when new documentation is released.

Comment by Sam Kleinman (Inactive) [ 15/Feb/12 ]

The new documentation reflects this behavior more clearly. I suspect that this will resolve this issue shortly.

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