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

Points near the poles may fail to be returned by $nearSphere with 2d index

    • Query Integration
    • ALL
    • Hide

      Apply the following patch and run python buildscripts/resmoke.py --executor=no_passthrough jstests/noPassthrough/geo_full.js.

      Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
      diff --git a/jstests/noPassthrough/geo_full.js b/jstests/noPassthrough/geo_full.js
      index 4912292..44ca81c 100644
      --- a/jstests/noPassthrough/geo_full.js
      +++ b/jstests/noPassthrough/geo_full.js
      @@ -24,8 +24,8 @@ db = testServer.getDB("test");
       
       var randEnvironment = function() {
       
      -    // Normal earth environment
      -    if (Random.rand() < 0.5) {
      +    // Always use the normal earth environment for simplicity.
      +    if (Random.rand() < 0.5 || true) {
               return {
                   max: 180,
                   min: -180,
      @@ -55,7 +55,8 @@ var randPoint = function(env, query) {
               return query.exact;
       
           if (env.earth)
      -        return [Random.rand() * 360 - 180, Random.rand() * 180 - 90];
      +        // Generate points at any longitude in [-180, 180) and only latitudes in [89, 90).
      +        return [Random.rand() * 360 - 180, 90 - Random.rand()];
       
           var range = env.max - env.min;
           return [Random.rand() * range + env.min, Random.rand() * range + env.min];
      
      Show
      Apply the following patch and run python buildscripts/resmoke.py --executor=no_passthrough jstests/noPassthrough/geo_full.js . Unable to find source-code formatter for language: diff. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml diff --git a/jstests/noPassthrough/geo_full.js b/jstests/noPassthrough/geo_full.js index 4912292..44ca81c 100644 --- a/jstests/noPassthrough/geo_full.js +++ b/jstests/noPassthrough/geo_full.js @@ -24,8 +24,8 @@ db = testServer.getDB( "test" ); var randEnvironment = function() { - // Normal earth environment - if (Random.rand() < 0.5) { + // Always use the normal earth environment for simplicity. + if (Random.rand() < 0.5 || true ) { return { max: 180, min: -180, @@ -55,7 +55,8 @@ var randPoint = function(env, query) { return query.exact; if (env.earth) - return [Random.rand() * 360 - 180, Random.rand() * 180 - 90]; + // Generate points at any longitude in [-180, 180) and only latitudes in [89, 90). + return [Random.rand() * 360 - 180, 90 - Random.rand()]; var range = env.max - env.min; return [Random.rand() * range + env.min, Random.rand() * range + env.min];
    • 0

      The GeoNear2DStage has its own implementation for projecting a spherical region to a flat annulus. siyuan.zhou and I read through the code and suspect the issue is with the computeXScanDistance() function, but aren't clear on the details (read: math) that cause $nearSphere queries to omit points from the flat annulus that were included in the spherical region.

      inline double computeXScanDistance(double y, double maxDistDegrees) {
          // TODO: this overestimates for large maxDistDegrees far from the equator
          return maxDistDegrees / std::min(cos(deg2rad(std::min(+89.0, y + maxDistDegrees))),
                                           cos(deg2rad(std::max(-89.0, y - maxDistDegrees))));
      }
      

      As a workaround, one can perform the $nearSphere queries with a "2dsphere" index to get the expected results.


      Note: This is a separate issue from the one reported in SERVER-21594, as the $maxDistance specified in to the $nearSphere query doesn't necessarily cause it to cross over the pole.

      Additionally, $geoWithin queries that use $centerSphere don't appear to be affected by this issue because they use the S2 library to perform the projection from the spherical region to the flat box.

            Assignee:
            backlog-query-integration [DO NOT USE] Backlog - Query Integration
            Reporter:
            max.hirschhorn@mongodb.com Max Hirschhorn
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated: