溢出排序阶段在尝试跳过MongoDB存储库时缓冲数据使用

时间:2015-05-21 20:54:35

标签: c# mongodb asp.net-web-api mongodb-.net-driver asp.net-web-api-odata

我有一个经典的REST和ODATA启用的Web API控制器调用基于MongoDB的存储库模式实现。

我一直在

  

溢出排序阶段缓冲数据使用量33556193字节超出内部限制33554432字节异常

当我尝试跳过第一个12010+记录并获得前10名时

?$skip=12020&$top=10&$orderby=Serial

经过一些搜索,我试图在Serial上实现一个索引,如

private void GetCollection() //is like DBSet of some entity
{
  _collection = _dbContext.Database
     .GetCollection<TEntity>(typeof(TEntity).Name);
  Type typeParameterType = typeof(TEntity);
  if (typeParameterType.Name == "StoreCommand")
    if (_collection.IndexExists("Serial") == false)
      _collection.CreateIndex(IndexKeys<StoreCommand>.Ascending(_ => _.Serial));
}

我的存储库实现是这样的。

    public class MongoDbRepository<TEntity> :
    IRepository<TEntity> where
        TEntity : EntityBase
{
    private MongoCollection<TEntity> _collection;

    private SNDbContext _dbContext;
    public MongoDbRepository(SNDbContext dbContext)
    {
        _dbContext = dbContext;
        GetCollection();
    }
    private void GetCollection()
    {
        _collection = _dbContext.Database
            .GetCollection<TEntity>(typeof(TEntity).Name);
    }
    public IQueryable<TEntity> GetAll()
    {
        return _collection.AsQueryable(); 
    }//............And other functions after this

}

来自服务层的呼叫就像这样

 IQueryable<StoreCommand> GetAllStoreCommands() 
  {
     return _uow.StoreCommands.GetAll(); 
   } 

其中SNDbContext具有与使用MongoClient和连接字符串获取数据库相关的所有代码。

1 个答案:

答案 0 :(得分:0)

问题在于,在您的存储库实现(未显示)中,您从MongoDB获取所有数据,然后所有这些数据都在缓冲中排序并在内存中排序以允许跳过和拍摄。

您需要做的是以下列两种方式修改您的存储库:

  • 返回一个纯可查询对象,以便您可以编写剩余的查询并仍然在MongoDB引擎上执行它
  • 直接公开接收要跳过和接受的参数的方法,并进行直接在数据库中执行它们的查询。

您可以使用游标实现它,如下所示:

var collection = db.GetCollection<YourType>("yourtype");
var sort = SortBy<YourType>
            .Ascending(p => p.YourProperty1)
            .Descending(p => p.YourProperty2);
MongoCursor<YourType> cursor = collection
  .FindAll()
  .SetSortOrder(sort)
  .SetSkip(12010)
  .SetLimit(10);

如果你迭代这个光标,你根本不应该遇到任何问题。

您还可以定义并执行SelectQuery,指定SkipTake值。请参阅文档:SelectQuery Properties