[SERVER-74298] Implement renaming by path component for PathMatchExpression Created: 23/Feb/23  Updated: 12/May/23

Status: Backlog
Project: Core Server
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Improvement Priority: Major - P3
Reporter: Yoon Soo Kim Assignee: Backlog - Query Optimization
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Issue split
split from SERVER-55492 Implement renames for kOther and kArr... Backlog
Related
is related to SERVER-75853 Have hasOnlyRenameableMatchExpression... Closed
Assigned Teams:
Query Optimization
Participants:

 Description   

While working on SERVER-73914, we realized that the current renaming algorithm does not support renaming by path component but we'd better to since it would support more splittable and renameable match expressions and hence achieve the better optimization. For example,

assuming that we have a pipeline like

[
    {
        $project: {
            x: {
                $map: {input: '$a', as: 'i', in : {y: '$$i.b'}}
            }
        }
    },
    {$match: {x: {y: 1}}}
]

the above $match should be able to be swapped with $project because $project is a simple rename.

But as of today, there are two related issues to support the above match expression.

1) semantic_analysis::extractModifiedDependencies() reports the path 'x' as a modified dependency and call splitMatchExpressionBy(expr, fields = {"x"}, renames = {"x.y" -> "a.b"}) and hence the expr is not splittable and cannot be swapped with $project.
2) PathMatchExpression::applyRename() cannot rename sub-fields of prefix of renamed paths.

We have the same issue for $elemMatch.

Search for SERVER-74298 for more details on what to do.

Also this note might be helpful.

And also this analysis too:
Right now, the match_expression::addDependencies() that uses DependencyVisitor does not report the sub-object field paths as dependencies. https://github.com/10gen/mongo/blob/38e430eb3e2ef271f958c165d5d50c38c956363e/src/mongo/db/matcher/match_expression_dependencies.cpp#L119

For example, {d: {$elemMatch: {e: 1, f: 1}} is transformed to the following tree:

                            $elemMatch
                            /         \
                           d         $and
                                    /     \
                                  $eq     $eq
                                 /   \   /   \
                                e     1 f     1

And the DependencyVisitor reports only “d” as the dependency, neither “d.e” nor “d.f”. So, if “d.e” and “d.f” happen to be renamed paths from “a.b” and “a.c” by the previous $project stage, for example,

{{{$project: {d: {$map: {input: "$a", as: "i", in: {e: "$$i.b", f: "$$i.c"}}}}}
{{{$match: {d: {$elemMatch: {e: 1, f: 1}}}}

The $project reports renamed paths [\{d.e, a.b}, \{d.f, a.c}] but the DependencyVisitor only reports “d” as the dependency. So, we should not be able to rename “d.e” and “d.f” because “d” itself is neither a renamed nor preserved path and hence considered as a modified path by extractModifiedDependencies().

I noticed that “d.e” and “d.f” are also not renameable in the following example:

{$project: {d: {$map: {input: "$a", as: "i", in: {e: "$$i.b", f: "$$i.c"}}}}}
{$match: {d: {e: 1, f: 1}}}

The {d: {e: 1, f: 1}} is transformed to the following tree:

                                $eq
                               /   \
                              d  {e: 1, f: 1}

Interestingly enough, {e: 1, f: 1} is not transformed to an $and expression at all. So, even though we have $elemMatch object expression renameable by sub path component, we would still have an issue with $eq match against an object.


Generated at Thu Feb 08 06:27:03 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.