Skip to content

Conversation

@sanych-sun
Copy link
Member

…ld equals parameter in predicate

@sanych-sun sanych-sun requested a review from rstam January 4, 2025 01:28
@sanych-sun sanych-sun requested a review from a team as a code owner January 4, 2025 01:28

public override AstNode VisitExprFilter(AstExprFilter node)
{
var optimizedNode = (AstExprFilter)base.VisitExprFilter(node);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to visit upfront, for easier handling of nested documents scenario.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to assume base.VisitExprFilter always returns an AstExprFilter? I guess looking at the source code we can convince ourselves that it does.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Even if it always returns VisitExprFilter for now, it's better to double-check.

mapExpression.In is AstBinaryExpression inBinaryExpression &&
inBinaryExpression.Operator == AstBinaryOperator.Eq &&
TryGetBinaryExpressionArguments(inBinaryExpression, out AstFieldPathExpression fieldPathExpression, out AstVarExpression varExpression) &&
fieldPathExpression.Path.Length > 1 && fieldPathExpression.Path[0] == '$' && fieldPathExpression.Path[1] != '$' &&
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we have some more elegant way to check if fieldPath points to the "current" variable?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean.

But anything that starts with $$ is not a field so I think that's all we need to check.


return optimizedNode;

static bool TryGetBinaryExpressionArguments<T1, T2>(AstBinaryExpression binaryExpression, out T1 arg1, out T2 arg2)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Theoretically could be reusable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can wait until there is a need.

@sanych-sun sanych-sun removed the request for review from a team January 4, 2025 01:31

public override AstNode VisitExprFilter(AstExprFilter node)
{
var optimizedNode = (AstExprFilter)base.VisitExprFilter(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it safe to assume base.VisitExprFilter always returns an AstExprFilter? I guess looking at the source code we can convince ourselves that it does.

fieldPathExpression.Path.Length > 1 && fieldPathExpression.Path[0] == '$' && fieldPathExpression.Path[1] != '$' &&
varExpression == mapExpression.As)
{
return AstFilter.In(AstFilter.Field(fieldPathExpression.Path.Substring(1)), inputArrayValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment just before this line to visualize the simplification being done:

// { $expr : { $anyElementTrue : { $map : { input : <constantArray>, as : "<var>", in : { $eq : ["$<dottedFieldName>", "$$<var>"] } } } } }
//      => { "<dottedFieldName>" : { $in : <constantArray> } }                   
return AstFilter.In(AstFilter.Field(fieldPathExpression.Path.Substring(1)), inputArrayValue);                                                         

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

mapExpression.In is AstBinaryExpression inBinaryExpression &&
inBinaryExpression.Operator == AstBinaryOperator.Eq &&
TryGetBinaryExpressionArguments(inBinaryExpression, out AstFieldPathExpression fieldPathExpression, out AstVarExpression varExpression) &&
fieldPathExpression.Path.Length > 1 && fieldPathExpression.Path[0] == '$' && fieldPathExpression.Path[1] != '$' &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what you mean.

But anything that starts with $$ is not a field so I think that's all we need to check.


return optimizedNode;

static bool TryGetBinaryExpressionArguments<T1, T2>(AstBinaryExpression binaryExpression, out T1 arg1, out T2 arg2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can wait until there is a need.


namespace MongoDB.Driver.Tests.Linq.Linq3Implementation.Jira
{
public class AnyEqualTests : Linq3IntegrationTest
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the file name we want for these tests?

@sanych-sun sanych-sun requested a review from rstam January 7, 2025 02:43
Copy link
Contributor

@rstam rstam left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! LGTM.

@sanych-sun sanych-sun merged commit 030d1ad into mongodb:main Jan 9, 2025
30 checks passed
@sanych-sun sanych-sun deleted the csharp5436 branch January 9, 2025 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants