In an aggregation pipeline such as the following, the $limit value is not pushed down into the $geoNear stage:
[
{
$geoNear: {
near: [0, 0],
distanceField: "dist",
spherical: true,
minDistance: 0,
maxDistance: 0.05,
query: ...
},
},
{$limit: 1},
]
Instead, the $geoNear stage will return up to as many document here as its member value _batchSizeCount dictates.
The value of _batchSizeCount is set here and currently defaults to 32.
That means the pipeline performs unnecessary work if the $limit value is low.
According to Glean, the reason is that the DocumentSourceGeoNear pipeline stage does not advertise that it can be swapped with a limiting stage. The following patch changes that, and makes the $geoNear stage adhere to the limit:
diff --git a/src/mongo/db/pipeline/document_source_geo_near.h b/src/mongo/db/pipeline/document_source_geo_near.h
--- a/src/mongo/db/pipeline/document_source_geo_near.h
+++ b/src/mongo/db/pipeline/document_source_geo_near.h
@@ -82,7 +82,12 @@ public:
TransactionRequirement::kAllowed,
LookupRequirement::kAllowed,
UnionRequirement::kAllowed);
+ // $geoNear produces results ordered by distance, so a following $skip or $limit can be
+ // applied by the underlying near query without changing the pipeline's results.
+ constraints.canSwapWithSkippingOrLimitingStage = true;
constraints.outputDependsOnSingleInput = true;
return constraints;
}
The patch above could be used as the basis for pushing the limit value into the $geoNear stage. However, it needs to be fully evaluated if making this change has any unwanted side effects and if it breaks any existing tests.