es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

[MongoDb][net core] Mejorar el rendimiento de Count

Estoy utilizando abp.io con MongoDB. Estoy escribiendo una búsqueda paginada y veo que el método Count de mongo es muy muy lento. Si lo quito, mi API se ejecuta en alrededor de 50-60ms, pero cuando lo agrego, tarda entre 700-1000ms.

public async Task<><a>> GetPagedList(dto input)
{
    if (input.FilterKeyword.IsNotNullOrEmpty())
        input.FilterKeyword = input.FilterKeyword.Trim();

    var query = (await repo.GetMongoQueryableAsync())
               .WhereIf(input.x != null, p => p.x == input.x)
               .WhereIf(input.y != null, t => t.y == input.y)
               .WhereIf(input.Id != null, t => t.Id == input.Id);

    var totalCount = query.Count();

    var pagedAndSortedResult = query.OrderBy(input.Sorting).PageBy(input).ToList();

    return new PagedResultDto<><a>>(
        totalCount,
        ObjectMapper.Map<><t>, List<a>>(pagedAndSortedResult)
        );
}

¿Existe alguna forma de mejorar el rendimiento del método Count? ¿O alguna solución alternativa para la búsqueda paginada?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una forma de mejorar el rendimiento es utilizar la tubería de agregación de MongoDB para obtener el recuento total de una manera más óptima. Aquí tienes un ejemplo:

    var totalCount = await repo.GetMongoQueryableAsync()
        .WhereIf(input.x != null, p => p.x == input.x)
        .WhereIf(input.y != null, t => t.y == input.y)
        .WhereIf(input.Id != null, t => t.Id == input.Id)
        .CountDocumentsAsync();
    

    Esto debería ser más rápido que el método Count() porque utiliza la tubería de agregación, que está optimizada para este tipo de operaciones.

    Como alternativa, puedes intentar utilizar una combinación de los métodos Skip() y Limit() para lograr la paginación sin tener que obtener el recuento total, pero esto puede no ser adecuado para todos los escenarios dependiendo del número de registros que se estén consultando:

    var pagedAndSortedResult = await repo.GetMongoQueryableAsync()
        .WhereIf(input.x != null, p => p.x == input.x)
        .WhereIf(input.y != null, t => t.y == input.y)
        .WhereIf(input.Id != null, t => t.Id == input.Id)
        .OrderBy(input.Sorting)
        .Skip(input.SkipCount)
        .Limit(input.MaxResultCount)
        .ToListAsync();
    
    return new PagedResultDto<a>(
        pagedAndSortedResult.Count,
        ObjectMapper.Map<><t>, List<a>>(pagedAndSortedResult)
    );
    

    Ten en cuenta que estas soluciones pueden tener algunas limitaciones y pueden no ser adecuadas para todos los escenarios, por lo que es importante probar y validar su rendimiento y funcionalidad para tu caso de uso particular.

Comments are closed.