diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/AggregationQueryTests.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/AggregationQueryTests.cs index d4a8d284..7e605d55 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/AggregationQueryTests.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/AggregationQueryTests.cs @@ -4,7 +4,6 @@ using System.Linq; using System.Threading.Tasks; using Exceptionless.DateTimeExtensions; -using Foundatio.Repositories.Elasticsearch.Extensions; using Foundatio.Repositories.Elasticsearch.Tests.Repositories.Models; using Foundatio.Repositories.Models; using Microsoft.Extensions.Time.Testing; @@ -106,47 +105,6 @@ await _employeeRepository.AddAsync(new Employee Assert.Equal(1, result.Aggregations.Cardinality("cardinality_twitter").Value); } - [Fact] - public async Task GetNestedAggregationsAsync() - { - var utcToday = new DateTimeOffset(DateTime.UtcNow.Year, 1, 1, 12, 0, 0, TimeSpan.FromHours(5)); - var employees = new List { - EmployeeGenerator.Generate(nextReview: utcToday.SubtractDays(2)), - EmployeeGenerator.Generate(nextReview: utcToday.SubtractDays(1)) - }; - employees[0].Id = "employee1"; - employees[0].Id = "employee2"; - employees[0].PeerReviews = new PeerReview[] { new PeerReview { ReviewerEmployeeId = employees[1].Id, Rating = 4 } }; - employees[1].PeerReviews = new PeerReview[] { new PeerReview { ReviewerEmployeeId = employees[0].Id, Rating = 5 } }; - - await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); - - var nestedAggQuery = _client.Search(d => d.Index("employees").Aggregations(a => a - .Nested("nested_reviewRating", h => h.Path("peerReviews") - .Aggregations(a1 => a1.Terms("terms_rating", t => t.Field("peerReviews.rating").Meta(m => m.Add("@field_type", "integer"))))) - )); - - var result = nestedAggQuery.Aggregations.ToAggregations(); - Assert.Single(result); - Assert.Equal(2, ((result["nested_reviewRating"] as Foundatio.Repositories.Models.SingleBucketAggregate).Aggregations["terms_rating"] as Foundatio.Repositories.Models.BucketAggregate).Items.Count); - - var nestedAggQueryWithFilter = _client.Search(d => d.Index("employees").Aggregations(a => a - .Nested("nested_reviewRating", h => h.Path("peerReviews") - .Aggregations(a1 => a1 - .Filter("user_" + employees[0].Id, f => f.Filter(q => q.Term(t => t.Field("peerReviews.reviewerEmployeeId").Value(employees[0].Id))) - .Aggregations(a2 => a2.Terms("terms_rating", t => t.Field("peerReviews.rating").Meta(m => m.Add("@field_type", "integer"))))) - )))); - - result = nestedAggQueryWithFilter.Aggregations.ToAggregations(); - Assert.Single(result); - - var filteredAgg = ((result["nested_reviewRating"] as Foundatio.Repositories.Models.SingleBucketAggregate).Aggregations["user_" + employees[0].Id] as Foundatio.Repositories.Models.SingleBucketAggregate); - Assert.NotNull(filteredAgg); - Assert.Single(filteredAgg.Aggregations.Terms("terms_rating").Buckets); - Assert.Equal("5", filteredAgg.Aggregations.Terms("terms_rating").Buckets.First().Key); - Assert.Equal(1, filteredAgg.Aggregations.Terms("terms_rating").Buckets.First().Total); - } - [Fact] public async Task GetAliasedNumberAggregationThatCausesMappingAsync() { diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/NestedFieldTests.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/NestedFieldTests.cs new file mode 100644 index 00000000..e850bac1 --- /dev/null +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/NestedFieldTests.cs @@ -0,0 +1,407 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Exceptionless.DateTimeExtensions; +using Foundatio.Repositories.Elasticsearch.Extensions; +using Foundatio.Repositories.Elasticsearch.Tests.Repositories.Models; +using Foundatio.Repositories.Models; +using Newtonsoft.Json; +using Xunit; +using Xunit.Abstractions; + +namespace Foundatio.Repositories.Elasticsearch.Tests; + +public sealed class NestedFieldTests : ElasticRepositoryTestBase +{ + private readonly IEmployeeRepository _employeeRepository; + + public NestedFieldTests(ITestOutputHelper output) : base(output) + { + _employeeRepository = new EmployeeRepository(_configuration); + } + + public override async Task InitializeAsync() + { + await base.InitializeAsync(); + await RemoveDataAsync(); + } + + [Fact] + public async Task FindAsync_WithNestedPeerReviewOrCondition_ReturnsMatchingEmployees() + { + // Arrange + List employees = + [ + EmployeeGenerator.Generate("alice_123", "Alice", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 5 } + ]), + EmployeeGenerator.Generate("bob_456", "Bob", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 4 } + ]), + EmployeeGenerator.Generate("charlie_789", "Charlie", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 2 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + var searchRepository = (ISearchableReadOnlyRepository)_employeeRepository; + + // Act + var results = await searchRepository.FindAsync(q => q.FilterExpression("peerReviews.rating:>=4 OR peerReviews.reviewerEmployeeId:bob_456")); + + // Assert + Assert.Equal(2, results.Documents.Count); + Assert.Contains(results.Documents, e => String.Equals(e.Name, "Alice")); + Assert.Contains(results.Documents, e => String.Equals(e.Name, "Bob")); + } + + [Fact] + public async Task CountAsync_WithNestedPeerReviewAggregation_ReturnsAggregationData() + { + // Arrange + List employees = + [ + EmployeeGenerator.Generate("alice_123", "Alice", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 5 }, + new PeerReview { ReviewerEmployeeId = "charlie_789", Rating = 4 } + ]), + EmployeeGenerator.Generate("bob_456", "Bob", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 3 }, + new PeerReview { ReviewerEmployeeId = "charlie_789", Rating = 5 } + ]), + EmployeeGenerator.Generate("charlie_789", "Charlie", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 2 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + + // Act + var result = await _employeeRepository.CountAsync(q => q.AggregationsExpression("terms:peerReviews.rating")); + + // Assert + Assert.Equal(3, result.Total); + Assert.Single(result.Aggregations); + Assert.NotEmpty(result.Aggregations); + + var nestedPeerReviewsAgg = result.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(nestedPeerReviewsAgg); + Assert.NotEmpty(nestedPeerReviewsAgg.Aggregations); + } + + [Fact] + public async Task FindAsync_WithNestedFieldInDefaultSearch_ReturnsMatchingEmployee() + { + // Arrange + const string specialReviewerId = "special_reviewer_123"; + List employees = + [ + EmployeeGenerator.Generate("alice_123", "Alice", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = specialReviewerId, Rating = 5 } + ]), + EmployeeGenerator.Generate("bob_456", "Bob", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 4 } + ]), + EmployeeGenerator.Generate("charlie_789", "Charlie", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 3 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + var searchRepository = (ISearchableReadOnlyRepository)_employeeRepository; + + // Act + var results = await searchRepository.FindAsync(q => q.SearchExpression(specialReviewerId)); + + // Assert + Assert.Single(results.Documents); + Assert.Equal("Alice", results.Documents.Single().Name); + } + + [Fact] + public async Task SearchAsync_WithNestedAggregations_ReturnsCorrectBuckets() + { + // Arrange + var utcToday = new DateTimeOffset(DateTime.UtcNow.Year, 1, 1, 12, 0, 0, TimeSpan.FromHours(5)); + List employees = + [ + EmployeeGenerator.Generate("employee1", nextReview: utcToday.SubtractDays(2), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 4 } + ]), + EmployeeGenerator.Generate("employee2", nextReview: utcToday.SubtractDays(1), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 5 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + + // Act + var nestedAggQuery = _client.Search(d => d.Index("employees").Aggregations(a => a + .Nested("nested_reviewRating", h => h.Path("peerReviews") + .Aggregations(a1 => a1.Terms("terms_rating", t => t.Field("peerReviews.rating").Meta(m => m.Add("@field_type", "integer"))))) + )); + + // Assert + var result = nestedAggQuery.Aggregations.ToAggregations(); + Assert.Single(result); + + var nestedReviewRatingAgg = result["nested_reviewRating"] as SingleBucketAggregate; + Assert.NotNull(nestedReviewRatingAgg); + + var termsRatingAgg = nestedReviewRatingAgg.Aggregations["terms_rating"] as BucketAggregate; + Assert.NotNull(termsRatingAgg); + Assert.Equal(2, termsRatingAgg.Items.Count); + + // Act - Test nested aggregation with filter + var nestedAggQueryWithFilter = _client.Search(d => d.Index("employees").Aggregations(a => a + .Nested("nested_reviewRating", h => h.Path("peerReviews") + .Aggregations(a1 => a1 + .Filter("user_" + employees[0].Id, f => f.Filter(q => q.Term(t => t.Field("peerReviews.reviewerEmployeeId").Value(employees[0].Id))) + .Aggregations(a2 => a2.Terms("terms_rating", t => t.Field("peerReviews.rating").Meta(m => m.Add("@field_type", "integer"))))) + )))); + + // Assert - Verify filtered aggregation + result = nestedAggQueryWithFilter.Aggregations.ToAggregations(); + Assert.Single(result); + + var nestedReviewRatingFilteredAgg = result["nested_reviewRating"] as SingleBucketAggregate; + Assert.NotNull(nestedReviewRatingFilteredAgg); + + var userFilteredAgg = nestedReviewRatingFilteredAgg.Aggregations["user_" + employees[0].Id] as SingleBucketAggregate; + Assert.NotNull(userFilteredAgg); + Assert.Single(userFilteredAgg.Aggregations.Terms("terms_rating").Buckets); + Assert.Equal("5", userFilteredAgg.Aggregations.Terms("terms_rating").Buckets.First().Key); + Assert.Equal(1, userFilteredAgg.Aggregations.Terms("terms_rating").Buckets.First().Total); + } + + [Fact] + public async Task CountAsync_WithNestedLuceneBasedAggregations_ReturnsCorrectMetrics() + { + // Arrange + var utcToday = new DateTimeOffset(DateTime.UtcNow.Year, 1, 1, 12, 0, 0, TimeSpan.FromHours(5)); + List employees = + [ + EmployeeGenerator.Generate("employee1", nextReview: utcToday.SubtractDays(2), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 5 } + ]), + EmployeeGenerator.Generate("employee2", nextReview: utcToday.SubtractDays(1), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 5 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 3 } + ]), + EmployeeGenerator.Generate("employee3", nextReview: utcToday.SubtractDays(3), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 5 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + const string aggregations = "terms:(peerReviews.reviewerEmployeeId peerReviews.rating) max:peerReviews.rating min:peerReviews.rating cardinality:peerReviews.reviewerEmployeeId"; + + // Act + var result = await _employeeRepository.CountAsync(q => q.AggregationsExpression(aggregations)); + + // Assert + Assert.Equal(3, result.Total); + Assert.Equal(2, result.Aggregations.Count); + + var nestedPeerReviewsAgg = result.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(nestedPeerReviewsAgg); + + var reviewerTermsAgg = nestedPeerReviewsAgg.Aggregations.Terms("terms_peerReviews.reviewerEmployeeId"); + Assert.Equal(3, reviewerTermsAgg.Buckets.Count); + + var ratingTermsAgg = nestedPeerReviewsAgg.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(3, ratingTermsAgg.Buckets.Count); + + Assert.Equal(3, nestedPeerReviewsAgg.Aggregations.Min("min_peerReviews.rating").Value); + Assert.Equal(5, nestedPeerReviewsAgg.Aggregations.Max("max_peerReviews.rating").Value); + Assert.Equal(3, nestedPeerReviewsAgg.Aggregations.Cardinality("cardinality_peerReviews.reviewerEmployeeId").Value); + } + + [Fact] + public async Task CountAsync_WithNestedAggregationsIncludeFiltering_ReturnsFilteredResults() + { + // Arrange + var utcToday = new DateTimeOffset(DateTime.UtcNow.Year, 1, 1, 12, 0, 0, TimeSpan.FromHours(5)); + List employees = + [ + EmployeeGenerator.Generate("employee1", nextReview: utcToday.SubtractDays(2), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 5 } + ]), + EmployeeGenerator.Generate("employee2", nextReview: utcToday.SubtractDays(1), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 5 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 3 } + ]), + EmployeeGenerator.Generate("employee3", nextReview: utcToday.SubtractDays(3), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 5 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + + // Act + const string aggregationsWithInclude = "terms:(peerReviews.reviewerEmployeeId~@include:employee1,employee2 peerReviews.rating~@include:4,5) max:peerReviews.rating min:peerReviews.rating"; + var resultWithInclude = await _employeeRepository.CountAsync(q => q.AggregationsExpression(aggregationsWithInclude)); + + // Assert + Assert.Equal(3, resultWithInclude.Total); + Assert.Equal(2, resultWithInclude.Aggregations.Count); + + var nestedPeerReviewsAggWithInclude = resultWithInclude.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(nestedPeerReviewsAggWithInclude); + + var reviewerTermsAggWithInclude = nestedPeerReviewsAggWithInclude.Aggregations.Terms("terms_peerReviews.reviewerEmployeeId"); + Assert.Equal(2, reviewerTermsAggWithInclude.Buckets.Count); // Only employee1 and employee2 should be included + Assert.Contains(reviewerTermsAggWithInclude.Buckets, b => String.Equals(b.Key, "employee1")); + Assert.Contains(reviewerTermsAggWithInclude.Buckets, b => String.Equals(b.Key, "employee2")); + Assert.DoesNotContain(reviewerTermsAggWithInclude.Buckets, b => String.Equals(b.Key, "employee3")); + + var ratingTermsAggWithInclude = nestedPeerReviewsAggWithInclude.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(2, ratingTermsAggWithInclude.Buckets.Count); // Only ratings 4 and 5 should be included + Assert.Contains(ratingTermsAggWithInclude.Buckets, b => b.Key == 4); + Assert.Contains(ratingTermsAggWithInclude.Buckets, b => b.Key == 5); + Assert.DoesNotContain(ratingTermsAggWithInclude.Buckets, b => b.Key == 3); + } + + [Fact] + public async Task CountAsync_WithNestedAggregationsExcludeFiltering_ReturnsFilteredResults() + { + // Arrange + var utcToday = new DateTimeOffset(DateTime.UtcNow.Year, 1, 1, 12, 0, 0, TimeSpan.FromHours(5)); + List employees = + [ + EmployeeGenerator.Generate("employee1", nextReview: utcToday.SubtractDays(2), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 5 } + ]), + EmployeeGenerator.Generate("employee2", nextReview: utcToday.SubtractDays(1), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 5 }, + new PeerReview { ReviewerEmployeeId = "employee3", Rating = 3 } + ]), + EmployeeGenerator.Generate("employee3", nextReview: utcToday.SubtractDays(3), peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "employee1", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "employee2", Rating = 5 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + + // Act + const string aggregationsWithExclude = "terms:(peerReviews.reviewerEmployeeId~@exclude:employee3 peerReviews.rating~@exclude:3) max:peerReviews.rating min:peerReviews.rating"; + var resultWithExclude = await _employeeRepository.CountAsync(q => q.AggregationsExpression(aggregationsWithExclude)); + + // Assert + Assert.Equal(3, resultWithExclude.Total); + Assert.Equal(2, resultWithExclude.Aggregations.Count); + + var nestedPeerReviewsAggWithExclude = resultWithExclude.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(nestedPeerReviewsAggWithExclude); + + var reviewerTermsAggWithExclude = nestedPeerReviewsAggWithExclude.Aggregations.Terms("terms_peerReviews.reviewerEmployeeId"); + Assert.Equal(2, reviewerTermsAggWithExclude.Buckets.Count); // employee3 should be excluded + Assert.Contains(reviewerTermsAggWithExclude.Buckets, b => String.Equals(b.Key, "employee1")); + Assert.Contains(reviewerTermsAggWithExclude.Buckets, b => String.Equals(b.Key, "employee2")); + Assert.DoesNotContain(reviewerTermsAggWithExclude.Buckets, b => String.Equals(b.Key, "employee3")); + + var ratingTermsAggWithExclude = nestedPeerReviewsAggWithExclude.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(2, ratingTermsAggWithExclude.Buckets.Count); // rating 3 should be excluded + Assert.Contains(ratingTermsAggWithExclude.Buckets, b => b.Key == 4); + Assert.Contains(ratingTermsAggWithExclude.Buckets, b => b.Key == 5); + Assert.DoesNotContain(ratingTermsAggWithExclude.Buckets, b => b.Key == 3); + } + + [Fact] + public async Task CountAsync_WithNestedAggregationsSerialization_CanRoundtripBothSerializers() + { + // Arrange + List employees = + [ + EmployeeGenerator.Generate("alice_123", "Alice", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 5 }, + new PeerReview { ReviewerEmployeeId = "charlie_789", Rating = 4 } + ]), + EmployeeGenerator.Generate("bob_456", "Bob", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 3 }, + new PeerReview { ReviewerEmployeeId = "charlie_789", Rating = 5 } + ]), + EmployeeGenerator.Generate("charlie_789", "Charlie", peerReviews: + [ + new PeerReview { ReviewerEmployeeId = "alice_123", Rating = 4 }, + new PeerReview { ReviewerEmployeeId = "bob_456", Rating = 2 } + ]) + ]; + + await _employeeRepository.AddAsync(employees, o => o.ImmediateConsistency()); + + // Act + var result = await _employeeRepository.CountAsync(q => q.AggregationsExpression("terms:peerReviews.rating max:peerReviews.rating min:peerReviews.rating")); + + // Assert + Assert.Equal(3, result.Total); + Assert.Single(result.Aggregations); + + var nestedPeerReviewsAgg = result.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(nestedPeerReviewsAgg); + + var ratingTermsAgg = nestedPeerReviewsAgg.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(4, ratingTermsAgg.Buckets.Count); + var bucket = ratingTermsAgg.Buckets.First(f => f.Key == 5); + Assert.Equal(2, bucket.Total); + + // Test Newtonsoft.Json serialization + string json = JsonConvert.SerializeObject(result); + var roundTripped = JsonConvert.DeserializeObject(json); + Assert.Equal(3, roundTripped.Total); + Assert.Single(roundTripped.Aggregations); + + var roundTrippedNestedAgg = roundTripped.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(roundTrippedNestedAgg); + + var roundTrippedRatingTermsAgg = roundTrippedNestedAgg.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(4, roundTrippedRatingTermsAgg.Buckets.Count); + bucket = roundTrippedRatingTermsAgg.Buckets.First(f => f.Key == 5); + Assert.Equal(2, bucket.Total); + + // Test System.Text.Json serialization + string systemTextJson = System.Text.Json.JsonSerializer.Serialize(result); + Assert.Equal(json, systemTextJson); + roundTripped = System.Text.Json.JsonSerializer.Deserialize(systemTextJson); + Assert.Equal(3, roundTripped.Total); + Assert.Single(roundTripped.Aggregations); + + roundTrippedNestedAgg = roundTripped.Aggregations["nested_peerReviews"] as SingleBucketAggregate; + Assert.NotNull(roundTrippedNestedAgg); + + roundTrippedRatingTermsAgg = roundTrippedNestedAgg.Aggregations.Terms("terms_peerReviews.rating"); + Assert.Equal(4, roundTrippedRatingTermsAgg.Buckets.Count); + bucket = roundTrippedRatingTermsAgg.Buckets.First(f => f.Key == 5); + Assert.Equal(2, bucket.Total); + } +} 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 5b74256d..bc2ca6c0 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Configuration/Indexes/EmployeeIndex.cs @@ -82,6 +82,10 @@ protected override void ConfigureQueryParser(ElasticQueryParserConfiguration con { base.ConfigureQueryParser(config); config.UseIncludes(ResolveIncludeAsync).UseOptInRuntimeFieldResolver(ResolveRuntimeFieldAsync); + config.SetDefaultFields([ + nameof(Employee.Id).ToLower(), + "peerReviews.reviewerEmployeeId" + ]); } private async Task ResolveIncludeAsync(string name) diff --git a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs index 61be56ff..3f72a508 100644 --- a/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs +++ b/tests/Foundatio.Repositories.Elasticsearch.Tests/Repositories/Models/Employee.cs @@ -150,7 +150,7 @@ public static class EmployeeGenerator EmploymentType = EmploymentType.FullTime }; - public static Employee Generate(string id = null, string name = null, int? age = null, int? yearsEmployed = null, string companyName = null, string companyId = null, string location = null, DateTime? lastReview = null, DateTimeOffset? nextReview = null, DateTime? createdUtc = null, DateTime? updatedUtc = null, EmploymentType? employmentType = null) + public static Employee Generate(string id = null, string name = null, int? age = null, int? yearsEmployed = null, string companyName = null, string companyId = null, string location = null, DateTime? lastReview = null, DateTimeOffset? nextReview = null, DateTime? createdUtc = null, DateTime? updatedUtc = null, EmploymentType? employmentType = null, PeerReview[] peerReviews = null) { return new Employee { @@ -165,7 +165,8 @@ public static Employee Generate(string id = null, string name = null, int? age = NextReview = nextReview.GetValueOrDefault(), CreatedUtc = createdUtc.GetValueOrDefault(), UpdatedUtc = updatedUtc.GetValueOrDefault(), - Location = location ?? RandomData.GetCoordinate() + Location = location ?? RandomData.GetCoordinate(), + PeerReviews = peerReviews }; }