Skip to content

Commit

Permalink
Cannot translate complex object filter on the right of where clause i…
Browse files Browse the repository at this point in the history
…n aggregation sets (#344)
  • Loading branch information
imansafari1991 committed Apr 14, 2023
1 parent d6982ee commit dbb71b8
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ protected override void ValidateAndPushOperand(Expression expression, Stack<stri
var val = ExpressionParserUtilities.GetValue(mem.Member, frame.Value);
stack.Push(BuildQueryPredicate(binaryExpression.NodeType, memberExpression.Member, System.Linq.Expressions.Expression.Constant(val)));
}
else
{
var val = ExpressionParserUtilities.GetOperandStringForQueryArgs(binaryExpression.Right);
stack.Push(BuildQueryPredicate(binaryExpression.NodeType, memberExpression.Member, System.Linq.Expressions.Expression.Constant(val)));
}

}
else if (expression is ConstantExpression c
&& c.Value.ToString() == "*")
Expand Down
19 changes: 18 additions & 1 deletion src/Redis.OM/Aggregation/RedisAggregation.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;
using Redis.OM.Aggregation.AggregationPredicates;

namespace Redis.OM.Aggregation
Expand Down Expand Up @@ -27,6 +28,10 @@ public RedisAggregation(string indexName)
/// </summary>
public QueryPredicate Query { get; set; } = new ();

/// <summary>
/// Gets or sets the query predicate.
/// </summary>
public List<QueryPredicate> Queries { get; set; } = new();
/// <summary>
/// Gets or sets the limit.
/// </summary>
Expand All @@ -43,8 +48,20 @@ public RedisAggregation(string indexName)
/// <returns>The serialized arguments.</returns>
public string[] Serialize()
{
var queries = new List<string>();
var ret = new List<string>() { IndexName };
ret.AddRange(Query.Serialize());
if (Queries.Any())
{
foreach (var query in Queries)
{
queries.AddRange(query.Serialize());
}
ret.AddRange(new[] { string.Join(" ", queries) });
}
else
{
ret.Add("*");
}
foreach (var predicate in Predicates)
{
ret.AddRange(predicate.Serialize());
Expand Down
10 changes: 1 addition & 9 deletions src/Redis.OM/Common/ExpressionTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,7 @@ public static RedisAggregation BuildAggregationFromExpression(Expression express
break;
case "Where":
lambda = (LambdaExpression)((UnaryExpression)exp.Arguments[1]).Operand;
if (i == expressions.Count - 1)
{
aggregation.Query = new QueryPredicate(lambda);
}
else
{
aggregation.Predicates.Push(new FilterPredicate(lambda.Body));
}

aggregation.Queries.Add(new QueryPredicate(lambda));
break;
case "Average":
case "AverageAsync":
Expand Down
15 changes: 15 additions & 0 deletions test/Redis.OM.Unit.Tests/CustomerFilterDto.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Redis.OM.Unit.Tests
{
internal class CustomerFilterDto
{
public string FirstName { get; set; }
public string LastName { get; set; }

}
}
30 changes: 30 additions & 0 deletions test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -448,5 +448,35 @@ public void TestMissedBinExpression()
.Apply(x=>x.RecordShell.Age + x["house_num_modified"] * 4 + x.RecordShell.Sales, "arbitrary_calculation").ToList();
_mock.Verify(x=>x.Execute("FT.AGGREGATE","person-idx", "*", "APPLY", "@Address_HouseNumber + 4", "AS", "house_num_modified", "APPLY", "@Age + @house_num_modified * 4 + @Sales", "AS", "arbitrary_calculation", "WITHCURSOR", "COUNT", "10000"));
}

[Fact]
public void TestWhereByComplexObjectOnTheRightSide()
{
var customerFilter = new CustomerFilterDto()
{
FirstName = "James",
LastName = "Bond"
};
var collection = new RedisAggregationSet<Person>(_mock.Object, true, chunkSize: 10000);
_mock.Setup(x => x.Execute("FT.AGGREGATE", It.IsAny<string[]>())).Returns(MockedResult);
_mock.Setup(x => x.Execute("FT.CURSOR", It.IsAny<string[]>())).Returns(MockedResultCursorEnd);
_ = collection.Where(x =>x.RecordShell.FirstName==customerFilter.FirstName) .ToList();
_mock.Verify(x => x.Execute("FT.AGGREGATE", "person-idx", "@FirstName:{James}", "WITHCURSOR", "COUNT", "10000"));
}

[Fact]
public void TestSequentialWhereClauseTranslation()
{
var customerFilter = new CustomerFilterDto()
{
FirstName = "James",
LastName = "Bond"
};
var collection = new RedisAggregationSet<Person>(_mock.Object, true, chunkSize: 10000);
_mock.Setup(x => x.Execute("FT.AGGREGATE", It.IsAny<string[]>())).Returns(MockedResult);
_mock.Setup(x => x.Execute("FT.CURSOR", It.IsAny<string[]>())).Returns(MockedResultCursorEnd);
_ = collection.Where(x => x.RecordShell.FirstName == customerFilter.FirstName).Where(p=>p.RecordShell.LastName==customerFilter.LastName).ToList();
_mock.Verify(x => x.Execute("FT.AGGREGATE", "person-idx", "@LastName:{Bond} @FirstName:{James}", "WITHCURSOR", "COUNT", "10000"));
}
}
}

0 comments on commit dbb71b8

Please sign in to comment.