简体   繁体   English

尝试从MongoDB存储库中跳过和获取数据时,溢出排序阶段缓冲了数据的使用

[英]Overflow sort stage buffered data usage when trying to skip and take from MongoDB repository

I have a classic REST and ODATA enabled Web API controller calling MongoDB based implementation of a repository pattern. 我有一个启用REST和ODATA的经典Web API控制器,它调用基于MongoDB的存储库模式实现。

I keep on getting 我不断

Overflow sort stage buffered data usage of 33556193 bytes exceeds internal limit of 33554432 byte Exception 溢出排序阶段缓冲的数据使用量33556193字节超过了内部限制33554432字节

when i try to skip first 12010+ records and get top 10 当我尝试跳过前12010年以上的记录并获得前10名时

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

After some search I tried to implement an index on Serial like 经过一些搜索后,我尝试在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));
}

My repository implementation is like this. 我的存储库实现是这样的。

    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

}

call from service layer is like this 来自服务层的呼叫是这样的

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

where SNDbContext has all the code related to getting me the Database using MongoClient and connection string. 其中SNDbContext具有与使用MongoClient和连接字符串获取数据库有关的所有代码。

The problem is that in your repository implementation (not shown) you're getting all the data from MongoDB, and then all this data is being sorted in buffered and sorted in memory to allow the skip and take. 问题在于,在存储库实现中(未显示),您将从MongoDB中获取所有数据,然后将所有这些数据存储在缓冲区中并在内存中进行排序以允许跳过和获取。

What you have to do is modify your repository in any of this two ways: 您要做的是通过以下两种方式之一来修改存储库:

  • return a pure queryable, so that you can compose the rest of the query and still get it executed on the MongoDB engine 返回一个纯可查询的内容,以便您可以组成其余的查询,并仍然使其在MongoDB引擎上执行
  • expose directly a method that receives parameters to skip and take, and make a query that executes them directly in the database. 直接公开一个方法,该方法接收要跳过和采用的参数,并进行查询以直接在数据库中执行这些参数。

You can implement it with a cursor, like this: 您可以使用游标实现它,如下所示:

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);

If you iterate this cursor you should not get any problem at all. 如果您迭代此游标,则根本不会出现任何问题。

You can also define and execute a SelectQuery , specifying the Skip and Take values. 您还可以定义和执行SelectQuery ,并指定SkipTake值。 See the docs: SelectQuery Properties 请参阅文档: SelectQuery属性

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM