-
Type: Improvement
-
Resolution: Fixed
-
Priority: Major - P3
-
Affects Version/s: None
-
Component/s: None
-
Query Optimization
-
Fully Compatible
-
QO 2022-12-26, QO 2023-01-09, QO 2023-01-23
There are a couple optimizations which can analyze projections and move a $match stage around, I'm thinking primarily of the work done in SERVER-27115, but there are probably others since then. We often skip $replaceRoot and leave it for future work. My understanding is that the thinking was that the stage is probably not that common and when it is used, is could (often?) be used in a way that is not optimizable (for instance, replacing with the result of some complex expression tree).
I have seen a couple cases recently where folks are using it to promote a sub-document to the top level, which does seem pretty optimizable for a query like
> db.example.aggregate([{$replaceWith: "$subDocument"}, {$match: {x: 2}}])
Could be replaced with
> db.example.aggregate([{$match: {"subDocument.x": 2}}, {$replaceWith: "$subDocument"}])
This may be particularly useful in a view definition, or in combination with an $unwind where you are looking at array entries.
It's worth noting that there are definitely some edge cases to consider and possibly some bugs and caveats hiding, but I think this optimization is safe in at least many cases.
- depends on
-
SERVER-87508 Update $replaceRoot to support match pushdown and apply renames through GetModPathsReturn API
- Closed
- is related to
-
SERVER-27115 Track fields renamed by $project in aggregation for index consideration
- Closed
- related to
-
SERVER-72038 Better projection analysis for $replace(With|Root)
- Open
-
SERVER-73253 Better path tracking when renaming nested/compound grouping fields
- Closed
-
SERVER-87507 Merge successive $replace(Root|With) stages
- Closed