Skip to content

Commit

Permalink
Apply includes and excludes to GetById and GetByIds
Browse files Browse the repository at this point in the history
  • Loading branch information
ejsmith committed Dec 17, 2024
1 parent 1cf3c57 commit d7c3a98
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using Foundatio.Repositories.Elasticsearch.CustomFields;
using Foundatio.Repositories.Elasticsearch.Extensions;
using Foundatio.Repositories.Elasticsearch.Queries.Builders;
using Foundatio.Repositories.Elasticsearch.Utility;
using Foundatio.Repositories.Exceptions;
using Foundatio.Repositories.Extensions;
using Foundatio.Repositories.Models;
Expand All @@ -18,6 +19,7 @@
using Foundatio.Utility;
using Microsoft.Extensions.Logging;
using Nest;
using Index = Foundatio.Repositories.Elasticsearch.Configuration.Index;

namespace Foundatio.Repositories.Elasticsearch;

Expand Down Expand Up @@ -101,8 +103,11 @@ public virtual async Task<T> GetByIdAsync(Id id, ICommandOptions options = null)
}

var request = new GetRequest(ElasticIndex.GetIndex(id), id.Value);

if (id.Routing != null)
request.Routing = id.Routing;

ConfigureGetRequest(request, options);
var response = await _client.GetAsync<T>(request).AnyContext();
_logger.LogRequest(response, options.GetQueryLogLevel());

Expand Down Expand Up @@ -153,6 +158,7 @@ public virtual async Task<IReadOnlyCollection<T>> GetByIdsAsync(Ids ids, IComman
});
}

ConfigureMultiGetRequest(multiGet, options);
var multiGetResults = await _client.MultiGetAsync(multiGet).AnyContext();
_logger.LogRequest(multiGetResults, options.GetQueryLogLevel());

Expand Down Expand Up @@ -714,6 +720,79 @@ protected virtual ICommandOptions<T> ConfigureOptions(ICommandOptions<T> options
return options;
}

protected virtual void ConfigureGetRequest(GetRequest request, ICommandOptions options)
{
var (resolvedIncludes, resolvedExcludes) = GetResolvedIncludesAndExcludes(options);

if (resolvedIncludes.Length > 0 && resolvedExcludes.Length > 0)
{
request.SourceIncludes = resolvedIncludes;
request.SourceExcludes = resolvedExcludes;
} else if (resolvedIncludes.Length > 0)
{
request.SourceIncludes = resolvedIncludes;
}
else if (resolvedExcludes.Length > 0)
{
request.SourceExcludes = resolvedExcludes;
}
}

protected virtual void ConfigureMultiGetRequest(MultiGetDescriptor request, ICommandOptions options)
{
var (resolvedIncludes, resolvedExcludes) = GetResolvedIncludesAndExcludes(options);

if (resolvedIncludes.Length > 0 && resolvedExcludes.Length > 0)
{
request.SourceIncludes(resolvedIncludes);
request.SourceExcludes(resolvedExcludes);
} else if (resolvedIncludes.Length > 0)
{
request.SourceIncludes(resolvedIncludes);
}
else if (resolvedExcludes.Length > 0)
{
request.SourceExcludes(resolvedExcludes);
}
}

private (Field[] Includes, Field[] Excludes) GetResolvedIncludesAndExcludes(ICommandOptions options)
{
return GetResolvedIncludesAndExcludes(null, options);
}

private (Field[] Includes, Field[] Excludes) GetResolvedIncludesAndExcludes(IRepositoryQuery query, ICommandOptions options)
{
// includes

var includes = new HashSet<Field>();
includes.AddRange(query.GetIncludes());
includes.AddRange(options.GetIncludes());

var optionIncludeMask = options.GetIncludeMask();
if (!String.IsNullOrEmpty(optionIncludeMask))
includes.AddRange(FieldIncludeParser.ParseFieldPaths(optionIncludeMask).Select(f => (Field)f));

var resolvedIncludes = ElasticIndex.MappingResolver.GetResolvedFields(includes).ToArray();

// excludes

var excludes = new HashSet<Field>();
includes.AddRange(query.GetExcludes());
excludes.AddRange(options.GetExcludes());

if (_defaultExcludes.Count > 0 && excludes.Count == 0)
excludes.AddRange(_defaultExcludes.Select(f => f.Value));

var optionExcludeMask = options.GetExcludeMask();
if (!String.IsNullOrEmpty(optionExcludeMask))
excludes.AddRange(FieldIncludeParser.ParseFieldPaths(optionExcludeMask).Select(f => (Field)f));

var resolvedExcludes = ElasticIndex.MappingResolver.GetResolvedFields(excludes).ToArray();

return (resolvedIncludes, resolvedExcludes);
}

private bool ShouldReturnDocument(T document, ICommandOptions options)
{
if (document == null)
Expand Down
2 changes: 1 addition & 1 deletion tests/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="xunit" Version="2.9.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.8.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="3.0.0" />

<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1" PrivateAssets="All" />

Expand Down
30 changes: 30 additions & 0 deletions tests/Foundatio.Repositories.Elasticsearch.Tests/QueryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,36 @@ public async Task CanHandleIncludeAndExclude()
Assert.Null(companyLog.CompanyId);
}

[Fact]
public async Task CanHandleIncludeAndExcludeOnGetById()
{
var log = await _dailyRepository.AddAsync(LogEventGenerator.Generate(companyId: "1234567890", message: "test", stuff: "stuff"), o => o.ImmediateConsistency());
Assert.NotNull(log?.Id);

var companyLog = await _dailyRepository.GetByIdAsync(log!.Id, o => o.QueryLogLevel(LogLevel.Warning).Exclude(e => e.Date).Include(e => e.Id).Include("createdUtc"));
Assert.Equal(log.Id, companyLog.Id);
Assert.Equal(log.CreatedUtc, companyLog.CreatedUtc);
Assert.Equal(default, companyLog.Date);
Assert.Null(companyLog.Message);
Assert.Null(companyLog.CompanyId);
}

[Fact]
public async Task CanHandleIncludeAndExcludeOnGetByIds()
{
var log = await _dailyRepository.AddAsync(LogEventGenerator.Generate(companyId: "1234567890", message: "test", stuff: "stuff"), o => o.ImmediateConsistency());
Assert.NotNull(log?.Id);

var results = await _dailyRepository.GetByIdsAsync([log!.Id], o => o.QueryLogLevel(LogLevel.Warning).Exclude(e => e.Date).Include(e => e.Id).Include("createdUtc"));
Assert.Single(results);
var companyLog = results.First();
Assert.Equal(log.Id, companyLog.Id);
Assert.Equal(log.CreatedUtc, companyLog.CreatedUtc);
Assert.Equal(default, companyLog.Date);
Assert.Null(companyLog.Message);
Assert.Null(companyLog.CompanyId);
}

[Fact]
public async Task GetByCompanyWithExcludeMask()
{
Expand Down

0 comments on commit d7c3a98

Please sign in to comment.