Starts in:
0 DAY
23 HRS
15 MIN
21 SEC
Starts in:
0 D
23 H
15 M
21 S
Open Closed

Cannot specify MongoDB AggregationOptions during GetMongoQueryableAsync and GetAggregateAsync calls #1102


User avatar
0
michael.sudnik created
  • ABP Framework version: v4.2.1
  • UI type: MVC
  • DB provider: MongoDB
  • Tiered (MVC) or Identity Server Separated (Angular): yes
  • Exception message and stack trace:
  • Steps to reproduce the issue:

I cannot find a nice way to specify the AggregationOptions used when using the GetMongoQueryableAsync or GetAggregateAsync methods.

Ideally, the following changes could be made:

  • add an "AggregateOptions options = null" parameter to both the GetMongoQueryableAsync and GetAggregateAsync methods
  • Create a virtual "CreateAggregationOptions" method on the AbpMongoDbContext to create the default AggregateOptions that should be used. Default return null.
  • Create a virtual "CreateAggregationOptions" method on the MongoDbRepository to create the default AggregateOptions that should be used. Default return value from IAbpMongoDbContext.CreateAggregationOptions.

By being able to control the AggregationOptions in this way, we can then specify the Collation setting for a whole module, repository or specific query. Ideally, I would also like to specify the default AggregationOptions used for my entire application. E.g. by configuring some mongodb options.

I would also want to ablity to override the aggregation options specified in other modules (presumably this would be possible by replacing the DBContext).

An example why this is neccesary... Without specifying the collation (and accompanying index within the database) we cannot make results be ordered in a case insensitive way. E.g. By default the list "A, b, D, e" is ordered as "A, D, b, e" if a collation is not specified (resulting in a binary simple collation always being used). By specifying a collation, we can ensure that a particular index is used, which is defined as having a strength of 1 or 2 (case and diacritic insensitive).

Another minor improvement, which would be useful during aggregation pipelines (e.g. lookup generation) would be if the AbpMongoDbContext.GetCollectionName<> method was made public.


4 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    Hi,

    Let's write an example code for AggregateAsync and Aggregate. Is this what you do when you don't have a GetMongoQueryableAsync() ? If yes, show me what's the final method signature of GetMongoQueryableAsync()

        public class MongoCellPhoneRepository : MongoDbRepository<Moongo03295343MongoDbContext, CellPhone, Guid>,
            ICellPhoneRepository
        {
            public MongoCellPhoneRepository(IMongoDbContextProvider<Moongo03295343MongoDbContext> dbContextProvider)
                : base(dbContextProvider)
            {
            }
    
            public async Task<List<CellPhone>> GetListAsync(CancellationToken cancellationToken = default)
            {
                var dbContext = await GetDbContextAsync(cancellationToken);
                var aggregateFluent = dbContext.CellPhones.Aggregate(new AggregateOptions
                {
                    Collation = new Collation("tr")
                });
    
                var asyncCursor = await dbContext.CellPhones.AggregateAsync(
                    new EmptyPipelineDefinition<CellPhone>(), new AggregateOptions
                    {
                        Collation = new Collation("tr")
                    }, cancellationToken);
            }
        }
    
  • User Avatar
    0
    michael.sudnik created

    I have inherited from the base MongoDBRepository and added the following method

    public virtual async Task<IAggregateFluent<TEntity>> GetMongoAggregatedAsync(CancellationToken cancellationToken, AggregateOptions options = null)
            {
                var sessionHandle = await GetSessionHandleAsync(cancellationToken);
    
                var collection = await GetCollectionAsync(cancellationToken);
    
                if (options == null)
                    options = (await GetDbContextAsync()).ProvideDefaultAggregateOptions();
    
                IAggregateFluent<TEntity> aggregate = sessionHandle != null ? collection.Aggregate(sessionHandle, options) : collection.Aggregate(options);
    
                return ApplyDataFilters(aggregate);
            }
    

    My dbcontext has the following

    public interface IExtendedMongoDbContext : IAbpMongoDbContext
        {
            string GetCollectionNamePublic<T>();
    
            AggregateOptions ProvideDefaultAggregateOptions();
        }
    

    I also have an equivalent new method for the GetMongoQueryableAsync.

    At the very least, it would be nice if these methods were virtual, so that they could at least be overriden within a repository, allowing the default aggregation options to be specified.

    https://github.com/abpframework/abp/blob/ef5f6fb81e5168d4e52493bc507c452e15692eae/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs#L514

    https://github.com/abpframework/abp/blob/ef5f6fb81e5168d4e52493bc507c452e15692eae/framework/src/Volo.Abp.MongoDB/Volo/Abp/Domain/Repositories/MongoDB/MongoDbRepository.cs#L528

  • User Avatar
    0
    alper created
    Support Team Director

    done https://github.com/abpframework/abp/commit/b1b9af0656216e39fe9d62420250d3fc00a47735

  • User Avatar
    0
    ServiceBot created
    Support Team Automatic process manager

    This question has been automatically marked as stale because it has not had recent activity.

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06