Skip to content

Commit

Permalink
allowing setting max in sortby
Browse files Browse the repository at this point in the history
  • Loading branch information
slorello89 committed Nov 20, 2024
1 parent 7783fa3 commit 465b3ac
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public AggregateSortBy(string property, SortDirection direction, int? max = null
/// <summary>
/// gets the number of arguments of this predicate.
/// </summary>
internal int NumArgs => Max.HasValue ? 4 : 2;
internal static int NumArgs => 2;

/// <inheritdoc/>
public IEnumerable<string> Serialize()
Expand Down
15 changes: 12 additions & 3 deletions src/Redis.OM/Aggregation/AggregationPredicates/MultiSort.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Redis.OM.Searching;

namespace Redis.OM.Aggregation.AggregationPredicates
{
Expand All @@ -22,11 +23,19 @@ public void InsertPredicate(AggregateSortBy sb)
/// <inheritdoc />
public IEnumerable<string> Serialize()
{
var numArgs = _subPredicates.Sum(x => x.NumArgs);
List<string> args = new List<string>(numArgs) { "SORTBY", numArgs.ToString() };
var numArgs = _subPredicates.Sum(x => AggregateSortBy.NumArgs);
var max = _subPredicates.FirstOrDefault(x => x.Max.HasValue)?.Max;
var args = new List<string>(numArgs) { "SORTBY", numArgs.ToString() };
foreach (var predicate in _subPredicates)
{
args.AddRange(predicate.Serialize().Skip(2));
args.Add($"@{predicate.Property}");
args.Add(predicate.Direction == SortDirection.Ascending ? "ASC" : "DESC");
}

if (max.HasValue)
{
args.Add("MAX");
args.Add(max.ToString());
}

return args;
Expand Down
5 changes: 5 additions & 0 deletions src/Redis.OM/Common/ExpressionTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,11 @@ private static AggregateSortBy TranslateSortBy(MethodCallExpression expression,
{
var member = GetFieldName(expression.Arguments[1]);
var sb = new AggregateSortBy(member, dir);
if (expression.Arguments.Count == 3)
{
sb.Max = (int)((ConstantExpression)expression.Arguments[2]).Value;
}

return sb;
}

Expand Down
36 changes: 36 additions & 0 deletions src/Redis.OM/SearchExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -929,6 +929,42 @@ public static RedisAggregationSet<T> OrderByDescending<T, TField>(this RedisAggr
return new RedisAggregationSet<T>(source, exp);
}

/// <summary>
/// Order the results by the provided field.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="expression">The expression to order by.</param>
/// <param name="max">the number of documents to sort.</param>
/// <typeparam name="T">The Indexed type.</typeparam>
/// <typeparam name="TField">The field type.</typeparam>
/// <returns>A set with the expression applied.</returns>
public static RedisAggregationSet<T> OrderBy<T, TField>(this RedisAggregationSet<T> source, Expression<Func<AggregationResult<T>, TField>> expression, int max)
{
var exp = Expression.Call(
null,
GetMethodInfo(OrderBy, source, expression, max),
new[] { source.Expression, Expression.Quote(expression), Expression.Constant(max) });
return new RedisAggregationSet<T>(source, exp);
}

/// <summary>
/// Order the results by the provided field.
/// </summary>
/// <param name="source">The source.</param>
/// <param name="expression">The expression to order by.</param>
/// <param name="max">The number of documents to sort.</param>
/// <typeparam name="T">The Indexed type.</typeparam>
/// <typeparam name="TField">The field type.</typeparam>
/// <returns>A set with the expression applied.</returns>
public static RedisAggregationSet<T> OrderByDescending<T, TField>(this RedisAggregationSet<T> source, Expression<Func<AggregationResult<T>, TField>> expression, int max)
{
var exp = Expression.Call(
null,
GetMethodInfo(OrderByDescending, source, expression, max),
new[] { source.Expression, Expression.Quote(expression), Expression.Constant(max) });
return new RedisAggregationSet<T>(source, exp);
}

/// <summary>
/// Closes out the group and yields a regular RedisAggregationSet. Use this to flush reductions further
/// down the pipeline.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ public void GetPeopleByAgeOrNameAndDepartment()
[Fact]
public void GetDepartmentBySales()
{
Setup();
var collection = new RedisAggregationSet<Person>(_connection);
var departments = collection
.Apply(x => x.RecordShell.Sales * x.RecordShell.SalesAdjustment, "AdjustedSales")
Expand All @@ -159,6 +160,23 @@ public void GetDepartmentBySales()
Assert.Equal(3, (int)departments[2]["DepartmentNumber"]);
Assert.Equal(2, (int)departments[3]["DepartmentNumber"]);
}

[Fact]
public void GetDepartmentBySalesWithMax()
{
Setup();
var collection = new RedisAggregationSet<Person>(_connection);
var departments = collection
.Apply(x => x.RecordShell.Sales * x.RecordShell.SalesAdjustment, "AdjustedSales")
.GroupBy(x => x.RecordShell.DepartmentNumber)
.Sum(x => x["AdjustedSales"])
.OrderByDescending(x => x["AdjustedSales_SUM"], int.MaxValue)
.ToArray();
Assert.Equal(1, (int)departments[0]["DepartmentNumber"]);
Assert.Equal(4, (int)departments[1]["DepartmentNumber"]);
Assert.Equal(3, (int)departments[2]["DepartmentNumber"]);
Assert.Equal(2, (int)departments[3]["DepartmentNumber"]);
}

[Fact]
public void GetHandicappedSales()
Expand Down
20 changes: 20 additions & 0 deletions test/Redis.OM.Unit.Tests/RediSearchTests/AggregationSetTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,26 @@ public void TestMultipleOrderBys()
_ = collection.OrderBy(x => x.RecordShell.Name).OrderByDescending(x => x.RecordShell.Age).ToList();
_substitute.Received().Execute("FT.AGGREGATE","person-idx", "*", "SORTBY", "4", "@Name", "ASC", "@Age", "DESC", "WITHCURSOR", "COUNT", "10000");
}

[Fact]
public void TestMultipleOrderByWithMax()
{
var collection = new RedisAggregationSet<Person>(_substitute, true, chunkSize: 10000);
_substitute.Execute("FT.AGGREGATE", Arg.Any<object[]>()).Returns(MockedResult);
_substitute.Execute("FT.CURSOR", Arg.Any<object[]>()).Returns(MockedResultCursorEnd);
_ = collection.OrderBy(x => x.RecordShell.Name, 42).OrderByDescending(x=>x.RecordShell.Age).ToList();
_substitute.Received().Execute("FT.AGGREGATE","person-idx", "*", "SORTBY", "4", "@Name", "ASC", "@Age", "DESC", "MAX", "42", "WITHCURSOR", "COUNT", "10000");
}

[Fact]
public void TestOrderByWithMax()
{
var collection = new RedisAggregationSet<Person>(_substitute, true, chunkSize: 10000);
_substitute.Execute("FT.AGGREGATE", Arg.Any<object[]>()).Returns(MockedResult);
_substitute.Execute("FT.CURSOR", Arg.Any<object[]>()).Returns(MockedResultCursorEnd);
_ = collection.OrderBy(x => x.RecordShell.Name, 42).ToList();
_substitute.Received().Execute("FT.AGGREGATE","person-idx", "*", "SORTBY", "2", "@Name", "ASC", "MAX", "42", "WITHCURSOR", "COUNT", "10000");
}

[Fact]
public void TestRightSideStringTypeFilter()
Expand Down

0 comments on commit 465b3ac

Please sign in to comment.