summaryrefslogtreecommitdiff
path: root/src/mongo/db/exec/geo_near.cpp
diff options
context:
space:
mode:
authorRuoxin Xu <ruoxin.xu@mongodb.com>2021-08-05 16:25:52 +0100
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-08-12 09:28:56 +0000
commit41d1ddba874968ba0268ba16adaf1823d027b5a2 (patch)
treeba84901765c910fb88e629fb56bc6c5bc8f7cbfd /src/mongo/db/exec/geo_near.cpp
parent95586a57c2126ebc4bf7c8970aade963ef61fe1d (diff)
downloadmongo-41d1ddba874968ba0268ba16adaf1823d027b5a2.tar.gz
SERVER-58745 Expose computeGeoNearDistance() as an internal-only DocumentSource
Diffstat (limited to 'src/mongo/db/exec/geo_near.cpp')
-rw-r--r--src/mongo/db/exec/geo_near.cpp76
1 files changed, 2 insertions, 74 deletions
diff --git a/src/mongo/db/exec/geo_near.cpp b/src/mongo/db/exec/geo_near.cpp
index 5a6d6beb9c8..0ce4f9ab856 100644
--- a/src/mongo/db/exec/geo_near.cpp
+++ b/src/mongo/db/exec/geo_near.cpp
@@ -57,8 +57,6 @@ namespace mongo {
using std::abs;
using std::unique_ptr;
-namespace dps = ::mongo::dotted_path_support;
-
//
// Shared GeoNear search functionality
//
@@ -67,77 +65,6 @@ static const double kCircOfEarthInMeters = 2 * M_PI * kRadiusOfEarthInMeters;
static const double kMaxEarthDistanceInMeters = kCircOfEarthInMeters / 2;
static const double kMetersPerDegreeAtEquator = kCircOfEarthInMeters / 360;
-namespace {
-
-/**
- * Structure that holds BSON addresses (BSONElements) and the corresponding geometry parsed
- * at those locations.
- * Used to separate the parsing of geometries from a BSONObj (which must stay in scope) from
- * the computation over those geometries.
- * TODO: Merge with 2D/2DSphere key extraction?
- */
-struct StoredGeometry {
- static StoredGeometry* parseFrom(const BSONElement& element) {
- if (!element.isABSONObj())
- return nullptr;
-
- unique_ptr<StoredGeometry> stored(new StoredGeometry);
-
- // GeoNear stage can only be run with an existing index
- // Therefore, it is always safe to skip geometry validation
- if (!stored->geometry.parseFromStorage(element, true).isOK())
- return nullptr;
- stored->element = element;
- return stored.release();
- }
-
- BSONElement element;
- GeometryContainer geometry;
-};
-} // namespace
-
-/**
- * Find and parse all geometry elements on the appropriate field path from the document.
- */
-static void extractGeometries(const BSONObj& doc,
- const string& path,
- std::vector<std::unique_ptr<StoredGeometry>>* geometries) {
- BSONElementSet geomElements;
- // NOTE: Annoyingly, we cannot just expand arrays b/c single 2d points are arrays, we need
- // to manually expand all results to check if they are geometries
- dps::extractAllElementsAlongPath(doc, path, geomElements, false /* expand arrays */);
-
- for (BSONElementSet::iterator it = geomElements.begin(); it != geomElements.end(); ++it) {
- const BSONElement& el = *it;
- unique_ptr<StoredGeometry> stored(StoredGeometry::parseFrom(el));
-
- if (stored.get()) {
- // Valid geometry element
- geometries->push_back(std::move(stored));
- } else if (el.type() == Array) {
- // Many geometries may be in an array
- BSONObjIterator arrIt(el.Obj());
- while (arrIt.more()) {
- const BSONElement nextEl = arrIt.next();
- stored.reset(StoredGeometry::parseFrom(nextEl));
-
- if (stored.get()) {
- // Valid geometry element
- geometries->push_back(std::move(stored));
- } else {
- LOGV2_WARNING(23760,
- "geoNear stage read non-geometry element in array",
- "nextElement"_attr = redact(nextEl),
- "element"_attr = redact(el));
- }
- }
- } else {
- LOGV2_WARNING(
- 23761, "geoNear stage read non-geometry element", "element"_attr = redact(el));
- }
- }
-}
-
static double computeGeoNearDistance(const GeoNearParams& nearParams, WorkingSetMember* member) {
//
// Generic GeoNear distance computation
@@ -152,7 +79,8 @@ static double computeGeoNearDistance(const GeoNearParams& nearParams, WorkingSet
// Extract all the geometries out of this document for the near query
std::vector<std::unique_ptr<StoredGeometry>> geometries;
- extractGeometries(member->doc.value().toBson(), nearParams.nearQuery->field, &geometries);
+ StoredGeometry::extractGeometries(
+ member->doc.value().toBson(), nearParams.nearQuery->field, &geometries, true);
// Compute the minimum distance of all the geometries in the document
double minDistance = -1;