[SERVER-11444] $lt/$lte/$gte/$gt behaves differently with array operand Created: 29/Oct/13  Updated: 17/Oct/16  Resolved: 07/Feb/14

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.4.5
Fix Version/s: 2.6.0-rc0

Type: Bug Priority: Major - P3
Reporter: Alvin Richards (Inactive) Assignee: Benety Goh
Resolution: Done Votes: 0
Labels: 26qa, nqf, query_triage
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

> db.serverBuildInfo( )
{
"version" : "2.5.4-pre-",
"gitVersion" : "d8ca8b5faa1447365403cfb8da16a041e7d31d95",
"OpenSSLVersion" : "",
"sysInfo" : "Darwin vero 12.5.0 Darwin Kernel Version 12.5.0: Sun Sep 29 13:33:47 PDT 2013; root:xnu-2050.48.12~1/RELEASE_X86_64 x86_64 BOOST_LIB_VERSION=1_49",
"loaderFlags" : "-fPIC -pthread -Wl,-bind_at_load -mmacosx-version-min=10.6",
"compilerFlags" : "-Wnon-virtual-dtor -Woverloaded-virtual -fPIC -fno-strict-aliasing -ggdb -pthread -Wno-unknown-pragmas -Winvalid-pch -pipe -O3 -Wno-unused-function -Wno-deprecated-declarations -mmacosx-version-min=10.6",
"allocator" : "tcmalloc",
"versionArray" : [
2,
5,
4,
-100
],
"javascriptEngine" : "V8",
"bits" : 64,
"debug" : false,
"maxBsonObjectSize" : 16777216,
"ok" : 1
}


Attachments: File server11444.js     File server11444.js    
Issue Links:
Duplicate
duplicates SERVER-11402 $gte/$gt behave differently when comp... Closed
duplicates SERVER-11403 $lt/$lte operator behaves differently... Closed
duplicates SERVER-11404 $nor operator behaves differently whe... Closed
duplicates SERVER-11405 $gt/$gte behavior change when compari... Closed
duplicates SERVER-11406 Change in behavior on how $gte work w... Closed
duplicates SERVER-11377 $gte doesn't match whole arrays but e... Closed
is duplicated by SERVER-12471 $all with array objects, differs in 2... Closed
Related
related to DOCS-2760 Document sort order for array fields Closed
related to SERVER-26655 $gt operation on array with index Closed
Backwards Compatibility: Major Change
Operating System: ALL
Participants:

 Description   

{$gt: [X]} matches arrays in 2.4.8 but not in 2.5.3. This is a change in the matcher behavior when the operand to the inequality operator is an array.

In 2.4.8, the matching behavior is affected by the level of nesting of the array.

In 2.5.3, the matcher returns zero documents as long as the element in the collection is an array.

--------------------

Problem:
A two level nested array produces different results in 2.5.4

NOTE: It appears that 2.5.4-Pre deals with this case correctly, if confirmed then this becomes a DOC tickets to list the changed behaviour.

Reproduce:

db.q.drop()
db.q.insert({"c" : { "c" : [ [ [ [ ISODate("1383-05-28T00:00:00Z") ] ] ] ] }})
db.q.insert({"c" : { "c" : [ [ [ ISODate("1383-05-28T00:00:00Z") ] ] ] }})
db.q.insert({"c" : { "c" : [ [ ISODate("1383-05-28T00:00:00Z") ] ] }})
db.q.insert({"c" : { "c" : [ ISODate("1383-05-28T00:00:00Z") ] }})
db.q.find( { $nor : [ { "c.c" : { $gt : [ [ ISODate("2013-09-29T10:40Z") ] ] } } ] } )

2.4.5
Returns 3 documents, but not the [ [ value ] ]

{ "_id" : ObjectId("526fdf7c8a43120c67c8c575"), "c" : { "c" : [  [  [  [  ISODate("1383-05-28T00:00:00Z") ] ] ] ] } }
{ "_id" : ObjectId("526fdf7c8a43120c67c8c576"), "c" : { "c" : [  [  [  ISODate("1383-05-28T00:00:00Z") ] ] ] } }
{ "_id" : ObjectId("526fdf7c8a43120c67c8c578"), "c" : { "c" : [  ISODate("1383-05-28T00:00:00Z") ] } }

2.5.4-Pre returns all documents

{ "_id" : ObjectId("526fdf886ca3a8357d0fe402"), "c" : { "c" : [  [  [  [  ISODate("1383-05-28T00:00:00Z") ] ] ] ] } }
{ "_id" : ObjectId("526fdf886ca3a8357d0fe403"), "c" : { "c" : [  [  [  ISODate("1383-05-28T00:00:00Z") ] ] ] } }
{ "_id" : ObjectId("526fdf886ca3a8357d0fe404"), "c" : { "c" : [  [  ISODate("1383-05-28T00:00:00Z") ] ] } }
{ "_id" : ObjectId("526fdf886ca3a8357d0fe405"), "c" : { "c" : [  ISODate("1383-05-28T00:00:00Z") ] } }

It appears that 2.4.x does not deal with the [ [ value ] ] case correctly.



 Comments   
Comment by Benety Goh [ 07/Feb/14 ]

inequality operators (lt/lte/gte/gt) now rely on compareElements to compare BSON elements just like other BSON types.

unit tests in matcher updated to demonstrate current behavior.

Comment by Githook User [ 07/Feb/14 ]

Author:

{u'username': u'benety', u'name': u'Benety Goh', u'email': u'benety@mongodb.com'}

Message: SERVER-11444 updated comparison operator to apply the same rules to arrays as other BSON types.
Branch: master
https://github.com/mongodb/mongo/commit/128b91e2bec8b9731c091771ba28a23f999d7b55

Comment by Eliot Horowitz (Inactive) [ 03/Feb/14 ]

The 2.4 behavior is correct.

Fundamentally

[1] > [0]

How to compare arrays: Take lowest element from each array, and compare.

For example:

db.test.insert( { c: [ [1] ] } );
db.test.find({c: {$gt: [0]}});

You can evaluate that as is [0] less than any element of c's array.
[0] is less than [1], so the doc should be returned.

Comment by Andrew Emil (Inactive) [ 27/Jan/14 ]

Another example:

> db.r.insert({_id:0, a: [[null]]})
SingleWriteResult({
        "writeErrors" : [ ],
        "writeConcernErrors" : [ ],
        "nInserted" : 1,
        "nUpserted" : 0,
        "nUpdated" : 0,
        "nModified" : 0,
        "nRemoved" : 0,
        "upserted" : [ ]
})
> db.r.find({a:{$lt: [""]}} )

Nothing is returned in 2.5, but in 2.4 the document is returned

Comment by Andrew Emil (Inactive) [ 19/Nov/13 ]

A super simple repro case:

>db.test.insert(

{c: [[1]]}

)
>db.test.find({c: {$gt: [0]}})

on 2.4 you get the inserted doc back, but on 2.5, nothing

Comment by Benety Goh [ 15/Nov/13 ]

Re-opened for further discussion

Comment by Mathias Stearn [ 15/Nov/13 ]

eliot I'm concerned about this being closed with $gte and $lte not matching arrays. That means that $gte doesn't return a superset of the document returned by equality matching (filed as SERVER-11377 which was marked a dup of this) .

Comment by Benety Goh [ 15/Nov/13 ]

inequality operators ($lt, $lte, $gte, $gt) do not match elements when the operand is an array:

Example:

{$lt: [X]}

Comment by Benety Goh [ 15/Nov/13 ]

new test script without $nor and date types

Comment by Daniel Pasette (Inactive) [ 30/Oct/13 ]

In 2.4.7, seems to also depend on the data type. Numbers are behaving slightly differently. Looks like this is a bug fixed in 2.5.4.

With the following docs:

{ "_id" : ObjectId("527149b1f8312bde42677fc6"), "c" : { "c" : [  [  [  [  1 ] ] ] ] } }
{ "_id" : ObjectId("527149b9f8312bde42677fc7"), "c" : { "c" : [  [  [  1 ] ] ] } }
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }

Results depend on level of nesting:

> db.q.find( { $nor : [ { "c.c" : { $gt : 2  } } ] } )
{ "_id" : ObjectId("527149b1f8312bde42677fc6"), "c" : { "c" : [  [  [  [  1 ] ] ] ] } }
{ "_id" : ObjectId("527149b9f8312bde42677fc7"), "c" : { "c" : [  [  [  1 ] ] ] } }
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }
 
> db.q.find( { $nor : [ { "c.c" : { $gt : [2]  } } ] } )
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }
 
> db.q.find( { $nor : [ { "c.c" : { $gt : [[2]]  } } ] } )
{ "_id" : ObjectId("527149b9f8312bde42677fc7"), "c" : { "c" : [  [  [  1 ] ] ] } }
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }
 
> db.q.find( { $nor : [ { "c.c" : { $gt : [[[2]]]  } } ] } )
{ "_id" : ObjectId("527149b1f8312bde42677fc6"), "c" : { "c" : [  [  [  [  1 ] ] ] ] } }
{ "_id" : ObjectId("527149b9f8312bde42677fc7"), "c" : { "c" : [  [  [  1 ] ] ] } }
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }
 
> db.q.find( { $nor : [ { "c.c" : { $gt : [[[[2]]]]  } } ] } )
{ "_id" : ObjectId("527149b1f8312bde42677fc6"), "c" : { "c" : [  [  [  [  1 ] ] ] ] } }
{ "_id" : ObjectId("527149b9f8312bde42677fc7"), "c" : { "c" : [  [  [  1 ] ] ] } }
{ "_id" : ObjectId("527149c0f8312bde42677fc8"), "c" : { "c" : [  [  1 ] ] } }
{ "_id" : ObjectId("527149c4f8312bde42677fc9"), "c" : { "c" : [  1 ] } }

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