From 70915426c26cc0e3de8152f2a41b19de6ce8178a Mon Sep 17 00:00:00 2001 From: randylsu Date: Mon, 20 May 2024 16:21:32 -0400 Subject: [PATCH] added support for decimal column sorting with SearchAfter & SearchBefore (#104) --- .../Extensions/FindHitExtensions.cs | 12 +++++++++++- .../ReadOnlyRepositoryTests.cs | 8 +++++--- .../Configuration/Indexes/EmployeeIndex.cs | 1 + .../Repositories/Models/Employee.cs | 1 + 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/Foundatio.Repositories.Elasticsearch/Extensions/FindHitExtensions.cs b/src/Foundatio.Repositories.Elasticsearch/Extensions/FindHitExtensions.cs index 9a0c7e5d..c2b3432c 100644 --- a/src/Foundatio.Repositories.Elasticsearch/Extensions/FindHitExtensions.cs +++ b/src/Foundatio.Repositories.Elasticsearch/Extensions/FindHitExtensions.cs @@ -144,7 +144,7 @@ public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonS { return reader.TokenType switch { - JsonTokenType.Number => reader.GetInt64(), + JsonTokenType.Number => GetNumber(reader), JsonTokenType.String => reader.GetString(), JsonTokenType.True => reader.GetBoolean(), JsonTokenType.False => reader.GetBoolean(), @@ -152,6 +152,16 @@ public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonS }; } + private object GetNumber(Utf8JsonReader reader) + { + if (reader.TryGetInt64(out var l)) + return l; + else if (reader.TryGetDecimal(out var d)) + return d; + else + throw new InvalidOperationException("Value is not a number"); + } + public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options) { throw new NotImplementedException(); diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/ReadOnlyRepositoryTests.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/ReadOnlyRepositoryTests.cs index 422db3ed..df383938 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/ReadOnlyRepositoryTests.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/ReadOnlyRepositoryTests.cs @@ -1201,8 +1201,10 @@ public async Task ShouldNotIncludeWhenDeletedAsync() Assert.Single(employees.Documents); } - [Fact] - public async Task CanSearchAfterAndBeforeWithMultipleSorts() + [Theory] + [InlineData("age")] + [InlineData("decimalAge")] + public async Task CanSearchAfterAndBeforeWithMultipleSorts(string secondarySort) { await _employeeRepository.AddAsync(EmployeeGenerator.GenerateEmployees(count: 100), o => o.ImmediateConsistency()); int pageSize = 10; @@ -1214,7 +1216,7 @@ public async Task CanSearchAfterAndBeforeWithMultipleSorts() do { page++; - var employees = await _employeeRepository.FindAsync(q => q.Sort(e => e.Name).Sort(e => e.CompanyName).SortDescending(e => e.Age), o => o.SearchAfterToken(searchAfterToken).PageLimit(pageSize).QueryLogLevel(LogLevel.Information)); + var employees = await _employeeRepository.FindAsync(q => q.Sort(e => e.Name).Sort(e => e.CompanyName).SortDescending(secondarySort), o => o.SearchAfterToken(searchAfterToken).PageLimit(pageSize).QueryLogLevel(LogLevel.Information)); searchBeforeToken = employees.GetSearchBeforeToken(); searchAfterToken = employees.GetSearchAfterToken(); if (page == 1) diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs index fcb7aa13..0815be82 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs @@ -50,6 +50,7 @@ public override TypeMappingDescriptor ConfigureIndexMapping(TypeMappin .Text(f => f.Name(e => e.Name).AddKeywordAndSortFields().CopyTo(c => c.Field("_all"))) .Scalar(f => f.Age, f => f.Name(e => e.Age)) .FieldAlias(a => a.Name("aliasedage").Path(f => f.Age)) + .Scalar(f => f.DecimalAge, f => f.Name(e => e.DecimalAge)) .Scalar(f => f.NextReview, f => f.Name(e => e.NextReview)) .FieldAlias(a => a.Name("next").Path(f => f.NextReview)) .GeoPoint(f => f.Name(e => e.Location)) diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs index 1b99d687..5c8b8c33 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs @@ -31,6 +31,7 @@ public class Employee : IIdentity, IHaveDates, IVersioned, ISupportSoftDeletes public string UnmappedEmailAddress => EmailAddress; public int Age { get; set; } public int UnmappedAge => Age; + public double DecimalAge => Age + .5; public string Location { get; set; } public int YearsEmployed { get; set; } public EmploymentType EmploymentType { get; set; } = EmploymentType.FullTime;