diff options
author | Ruoxin Xu <ruoxin.xu@mongodb.com> | 2021-08-05 16:25:52 +0100 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2021-08-12 09:28:56 +0000 |
commit | 41d1ddba874968ba0268ba16adaf1823d027b5a2 (patch) | |
tree | ba84901765c910fb88e629fb56bc6c5bc8f7cbfd /src/mongo/db/exec/geo_near.cpp | |
parent | 95586a57c2126ebc4bf7c8970aade963ef61fe1d (diff) | |
download | mongo-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.cpp | 76 |
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; |