Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-7915

Appending sort() executes $or operator with geospatial indexing when it should result in an user assert.

    • Type: Icon: Bug Bug
    • Resolution: Won't Fix
    • Priority: Icon: Minor - P4 Minor - P4
    • None
    • Affects Version/s: 2.4.10
    • Component/s: Geo, Querying
    • Labels:
      None
    • Environment:
      n/a
    • ALL

      //insert some geo stuff in a "locations" collection

      db.locations.insert( { name : "london", loc : [ 51.5073346, 0.12768310000001293 ] })
      
      db.locations.insert( { name : "guildford", loc : [51.23622, 0.5704090000000406] })
      
      db.locations.insert( { name : "farnborough", loc : [51.2868939, 0.7526149999999916] })
      
      db.locations.insert( { name : "camberley", loc : [51.3353899, 0.7428559999999607] })
      
      db.locations.insert( { name : "cheltenham", loc : [51.897599, 2.075608999999986] })
      
      db.locations.insert( { name : "bristol", loc : [51.454513, 2.5879099999999653] })
      
      db.locations.insert( { name : "reading", loc : [51.4528837, 0.9739059999999427] })
      

      // simple geo find

      db.locations.find({ loc : { $nearSphere : [51.2868, 0.7526], $maxDistance : 0.002523 } }) 
      

      // here is an $OR, which fails correctly and generates the appropriate user assert:

      db.locations.find({ 
              "$or" : [ 
                      {
                              "loc" : { "$nearSphere" : [51.2868, 0.7526], "$maxDistance" : 0.002523 }
                      }, 
                      {
                              "name" : "London"
                      } 
              ]
      }) 
      
      error: { "$err" : "$or may not contain 'special' query", "code" : 13291 }
      

      Appending sort() results in the query being executed instead of the user assert (Code 13291) being generated.

       db.locations.find({         "$or" : [                  {                         "loc" : { "$nearSphere" : [51.2868, 0.7526], "$maxDistance" : 0.002523 }                 },                  {                         "name" : "London"                 }          ] }).sort({ "DoesNotExist" : 1 });
      { "_id" : ObjectId("50c8ce18a17a909731b0d384"), "name" : "london", "loc" : [ 51.5073346, 0.12768310000001293 ] }
      { "_id" : ObjectId("50c8ce18a17a909731b0d385"), "name" : "guildford", "loc" : [ 51.23622, 0.5704090000000406 ] }
      { "_id" : ObjectId("50c8ce18a17a909731b0d386"), "name" : "farnborough", "loc" : [ 51.2868939, 0.7526149999999916 ] }
      { "_id" : ObjectId("50c8ce18a17a909731b0d387"), "name" : "camberley", "loc" : [ 51.3353899, 0.7428559999999607 ] }
      { "_id" : ObjectId("50c8ce18a17a909731b0d388"), "name" : "cheltenham", "loc" : [ 51.897599, 2.075608999999986 ] }
      { "_id" : ObjectId("50c8ce18a17a909731b0d389"), "name" : "bristol", "loc" : [ 51.454513, 2.5879099999999653 ] }
      { "_id" : ObjectId("50c8ce19a17a909731b0d38a"), "name" : "reading", "loc" : [ 51.4528837, 0.9739059999999427 ] }
      

      which based on the code does not appear to be correct behaviour.

      mongo/src/mongo/db/queryutil.cpp

         _orSets.push_back( FieldRangeSetPair( ns, f.embeddedObject(), optimize ) );
                          uassert( 13291, "$or may not contain 'special' query", _orSets.back().getSpecial().empty() );
                          _originalOrSets.push_back( _orSets.back() );
      

            Assignee:
            Unassigned Unassigned
            Reporter:
            mark Mark porter
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: