Mongo 即使在使用分页时也给我 "sort exceeded memory limit" 异常
Mongo gives me "sort exceeded memory limit" exception even when using pagination
我正在尝试使用 MongoDB 为我的项目创建分页搜索。即使使用 Limit 和 Skip,它也会抛出“Sort Exceeded Memory Limit”异常。这有点奇怪,因为我将查询限制为仅 10 个项目。
public async Task<(List<Contato>, long)> BuscarPorFiltro(FiltroContatoDTO filtro, int page, int pageSize)
{
var collection = _mongoDBContext.MongoDBConexao.GetCollection<Contato>(_collection);
var idsFluxoCompleto = await fluxoCompletoRepository.BuscarFluxoCompletoPorEmpresaId(Guid.Parse(filtro.EmpresaId));
var sortBuilder = Builders<Contato>.Sort;
var sort = sortBuilder.Descending(c => c.DataHora);
var options = new FindOptions<Contato>();
options.Skip = page * pageSize;
options.Limit = pageSize;
options.Sort = sort;
var filterBuilder = Builders<Contato>.Filter;
var filter = idsFluxoCompleto != null && idsFluxoCompleto.Count > 0 ? filterBuilder.Where(c => idsFluxoCompleto.Contains(c.IdFluxoCompleto)) : filterBuilder.Empty;
//Filtros Opcionais
if (filtro.DataInicio.HasValue)
filter = filter & filterBuilder.Gte(x => x.DataHora, filtro.DataInicio.Value);
if (filtro.DataFim.HasValue)
filter = filter & filterBuilder.Lt(x => x.DataHora, filtro.DataFim.Value);
if (filtro.FluxoId.HasValue)
filter = filter & filterBuilder.Eq(x => x.IdFluxoCompleto, filtro.FluxoId.Value);
if (!String.IsNullOrWhiteSpace(filtro.Telefone))
filter = filter & filterBuilder.Where(x => x.Telefone.Contains(filtro.Telefone));
if (filtro.CompletouFluxo.HasValue)
filter = filter & filterBuilder.Eq(x => x.Status, filtro.CompletouFluxo.Value);
if (filtro.CancelouFluxo.HasValue)
filter = filter & filterBuilder.Eq(x => x.CancelouFluxo, filtro.CancelouFluxo.Value);
if (filtro.IntegrouCRM.HasValue)
filter = filter & filterBuilder.Eq(x => x.RealizouIntegracaoCRM, filtro.IntegrouCRM.Value);
if (filtro.Ultrapassou24Horas.HasValue)
filter = filter & filterBuilder.Eq(x => x.Ultrapassou24Horas, filtro.Ultrapassou24Horas.Value);
if (!String.IsNullOrWhiteSpace(filtro.Temperatura))
filter = filter & filterBuilder.Eq(x => x.Lead, filtro.Temperatura.ToUpper());
if (filtro.Origem.HasValue)
filter = filter & filterBuilder.Eq(x => x.Origem, filtro.Origem.Value);
if (filtro.Unidade.HasValue)
filter = filter & filterBuilder.Eq(x => x.Unidade, filtro.Unidade.Value);
var count = await collection.CountDocumentsAsync(filter);
var result = await collection.FindAsync(filter, options);
return (result.ToList(), count);
}
我知道 AllowDiskUse 选项,但我不想使用它,因为这个特定查询应该 return只有 10 个项目,并且不应超过 returned 文档的 100Mb 限制。
虽然您将结果限制为 10 个文档,但 DB 必须过滤所有匹配文档并根据您的排序标准进行排序,如果整个匹配数据集不适合内存限制,DB 将抛出错误。
考虑这样一种情况,您有 10,000 个文档,您编写了将匹配文档减少到 5000 个的过滤器,然后您有一些 sort/skip 条件,然后数据库必须对匹配的 5000 个文档进行排序和跳过文档,如果这 5000 个文档不适合内存,它会抛出错误。
将 Allow disk use flag 设置为 true 没有坏处,只有当匹配的数据集大小不符合限制时才会使用它。
文档:https://docs.mongodb.com/manual/reference/command/aggregate/#command-fields
我正在尝试使用 MongoDB 为我的项目创建分页搜索。即使使用 Limit 和 Skip,它也会抛出“Sort Exceeded Memory Limit”异常。这有点奇怪,因为我将查询限制为仅 10 个项目。
public async Task<(List<Contato>, long)> BuscarPorFiltro(FiltroContatoDTO filtro, int page, int pageSize)
{
var collection = _mongoDBContext.MongoDBConexao.GetCollection<Contato>(_collection);
var idsFluxoCompleto = await fluxoCompletoRepository.BuscarFluxoCompletoPorEmpresaId(Guid.Parse(filtro.EmpresaId));
var sortBuilder = Builders<Contato>.Sort;
var sort = sortBuilder.Descending(c => c.DataHora);
var options = new FindOptions<Contato>();
options.Skip = page * pageSize;
options.Limit = pageSize;
options.Sort = sort;
var filterBuilder = Builders<Contato>.Filter;
var filter = idsFluxoCompleto != null && idsFluxoCompleto.Count > 0 ? filterBuilder.Where(c => idsFluxoCompleto.Contains(c.IdFluxoCompleto)) : filterBuilder.Empty;
//Filtros Opcionais
if (filtro.DataInicio.HasValue)
filter = filter & filterBuilder.Gte(x => x.DataHora, filtro.DataInicio.Value);
if (filtro.DataFim.HasValue)
filter = filter & filterBuilder.Lt(x => x.DataHora, filtro.DataFim.Value);
if (filtro.FluxoId.HasValue)
filter = filter & filterBuilder.Eq(x => x.IdFluxoCompleto, filtro.FluxoId.Value);
if (!String.IsNullOrWhiteSpace(filtro.Telefone))
filter = filter & filterBuilder.Where(x => x.Telefone.Contains(filtro.Telefone));
if (filtro.CompletouFluxo.HasValue)
filter = filter & filterBuilder.Eq(x => x.Status, filtro.CompletouFluxo.Value);
if (filtro.CancelouFluxo.HasValue)
filter = filter & filterBuilder.Eq(x => x.CancelouFluxo, filtro.CancelouFluxo.Value);
if (filtro.IntegrouCRM.HasValue)
filter = filter & filterBuilder.Eq(x => x.RealizouIntegracaoCRM, filtro.IntegrouCRM.Value);
if (filtro.Ultrapassou24Horas.HasValue)
filter = filter & filterBuilder.Eq(x => x.Ultrapassou24Horas, filtro.Ultrapassou24Horas.Value);
if (!String.IsNullOrWhiteSpace(filtro.Temperatura))
filter = filter & filterBuilder.Eq(x => x.Lead, filtro.Temperatura.ToUpper());
if (filtro.Origem.HasValue)
filter = filter & filterBuilder.Eq(x => x.Origem, filtro.Origem.Value);
if (filtro.Unidade.HasValue)
filter = filter & filterBuilder.Eq(x => x.Unidade, filtro.Unidade.Value);
var count = await collection.CountDocumentsAsync(filter);
var result = await collection.FindAsync(filter, options);
return (result.ToList(), count);
}
我知道 AllowDiskUse 选项,但我不想使用它,因为这个特定查询应该 return只有 10 个项目,并且不应超过 returned 文档的 100Mb 限制。
虽然您将结果限制为 10 个文档,但 DB 必须过滤所有匹配文档并根据您的排序标准进行排序,如果整个匹配数据集不适合内存限制,DB 将抛出错误。
考虑这样一种情况,您有 10,000 个文档,您编写了将匹配文档减少到 5000 个的过滤器,然后您有一些 sort/skip 条件,然后数据库必须对匹配的 5000 个文档进行排序和跳过文档,如果这 5000 个文档不适合内存,它会抛出错误。
将 Allow disk use flag 设置为 true 没有坏处,只有当匹配的数据集大小不符合限制时才会使用它。
文档:https://docs.mongodb.com/manual/reference/command/aggregate/#command-fields