diff options
author | Siyuan Zhou <visualzhou@gmail.com> | 2015-03-24 16:24:32 -0400 |
---|---|---|
committer | Siyuan Zhou <visualzhou@gmail.com> | 2015-03-25 17:18:28 -0400 |
commit | 3ee2c5c5c2c4ad0534138d567ccc7b053defff4a (patch) | |
tree | 76679ff70aceb4ed1be79686593918793ebba488 /src/mongo/db/exec/geo_near.cpp | |
parent | d5cd0b603f5f60f7e63523fac31a2a00aa0114f8 (diff) | |
download | mongo-3ee2c5c5c2c4ad0534138d567ccc7b053defff4a.tar.gz |
SERVER-17469 Enable density estimator for 2d nearSphere.
Diffstat (limited to 'src/mongo/db/exec/geo_near.cpp')
-rw-r--r-- | src/mongo/db/exec/geo_near.cpp | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/src/mongo/db/exec/geo_near.cpp b/src/mongo/db/exec/geo_near.cpp index 9026afc7239..96441e492a8 100644 --- a/src/mongo/db/exec/geo_near.cpp +++ b/src/mongo/db/exec/geo_near.cpp @@ -433,11 +433,6 @@ namespace mongo { Collection* collection, WorkingSetID* out) { - if (SPHERE == _nearParams.nearQuery->centroid->crs) { - _boundsIncrement = kMaxEarthDistanceInMeters / 1000.0; - return PlanStage::IS_EOF; - } - if (!_densityEstimator) { _densityEstimator.reset(new DensityEstimator(_twoDIndex, &_nearParams)); } @@ -447,8 +442,28 @@ namespace mongo { &estimatedDistance); if (state == PlanStage::IS_EOF) { + // 2d index only works with legacy points as centroid. $nearSphere will project + // the point into SPHERE CRS and calculate distance based on that. + // STRICT_SPHERE is impossible here, as GeoJSON centroid is not allowed for 2d index. + // Estimator finished its work, we need to finish initialization too. - _boundsIncrement = 3 * estimatedDistance; + if (SPHERE == _nearParams.nearQuery->centroid->crs) { + // Estimated distance is in degrees, convert it to meters. + _boundsIncrement = deg2rad(estimatedDistance) * kRadiusOfEarthInMeters * 3; + // Limit boundsIncrement to ~20KM, so that the first circle won't be too aggressive. + _boundsIncrement = std::min(_boundsIncrement, kMaxEarthDistanceInMeters / 1000.0); + } + else { + // We expand the radius by 3 times to give a reasonable starting search area. + // Assume points are distributed evenly. X is the edge size of cells at whose + // level we found a document in 4 neighbors. Thus the closest point is at least + // X/2 far from the centroid. The distance between two points is at least X. + // The area of Pi * (3X)^2 ~= 28 * X^2 will cover dozens of points at most. + // We'll explore the space with exponentially increasing radius if this guess is + // too small, so starting from a conservative initial radius doesn't hurt. + + _boundsIncrement = 3 * estimatedDistance; + } invariant(_boundsIncrement > 0.0); // Clean up |