【问题标题】:C# MongoDB driver only returning 100 resultsC# MongoDB 驱动程序只返回 100 个结果
【发布时间】:2017-09-15 19:37:49
【问题描述】:

我正在写一个邮寄标签,需要为每个文档打印一个标签。

我在 Collection 上有 829 个文档,但是当我检索它们时,我只得到 100 个文档。

我有这个 LINQ 代码:

IMongoCollection Pessoa;
Pessoa = database.GetCollection<Pessoa>(collectionName);

return Pessoa.AsQueryable().ToList();

如何检索所有文档?

【问题讨论】:

  • return Pessoa.AsQueryable().OrderBy(d => d.Nome).ToList(); Stills 只检索 100 个文档。
  • 也许您在任何地方设置了Limit
  • 所有对象的 Nome 属性都有值吗?
  • 是的,都填充了 Nome 属性。任何地方都没有限制。
  • 假设Pessoa 是集合,AsQueryable() 会导致聚合框架调用。您能否检查these methods 之一是否适合您?

标签: c# mongodb linq azure-cosmosdb


【解决方案1】:

我在 Collection 上有 829 个文档,但是当我检索它们时,我只得到 100 个文档。

我可以重现我这边的问题,使用 IMongoCollection collection.AsQueryable() 上的 AsQueryable 扩展方法来查找集合中的文档,即使我将 每页项目数 设置更改为无限制,它也始终返回 100 个文档在 Azure 门户上。

设置:

测试代码:

在查询资源管理器中计算文档数:

要查询集合中的所有文档,正如您在评论中提到的,您可以尝试使用空过滤器调用 Find method

【讨论】:

  • 我测试并确认返回 100 个文档的默认行为也发生在非 Microsoft 服务器上,如 Mongo Atlas。
【解决方案2】:

您可能受到默认cursor BatchSize 的限制。 您可以修改此行为,将AggregateOptions 对象传递给AsQueryable 扩展并将BatchSize 属性设置为足够大的值。

public static IMongoQueryable<TDocument> AsQueryable<TDocument>(this IMongoCollection<TDocument> collection, AggregateOptions aggregateOptions = null)

【讨论】:

    【解决方案3】:

    我觉得这个问题很有用,所以写了一个方便的IEnumerator

            private sealed class MongoCollectionEnumerator : IEnumerator<T> {
                private IMongoCollection<T> _collection;
                private IAsyncCursor<T> _cursor; // outer enumerator
                private IEnumerator<T> _currentBatchEnumerator; // inner enumerator
    
                public MongoCollectionEnumerator(IMongoCollection<T> collection) {
                    _collection = collection;
    
                    InternalInit();
                }
    
                #region interface implementation
                T IEnumerator<T>.Current {
                    get {
                        return _currentBatchEnumerator.Current;
                    }
                }
    
                object IEnumerator.Current {
                    get {
                        return ThisAsTypedIEnumerator.Current;
                    }
                }
    
                bool IEnumerator.MoveNext() {
                    if (_currentBatchEnumerator != null) {
                        if (_currentBatchEnumerator.MoveNext()) {
                            return true;
                        }
                    }
    
                    // inner not initialized or already at end
                    if (_cursor.MoveNext()) {
                        // advance the outer and defer back to the inner by recursing
                        _currentBatchEnumerator = _cursor.Current.GetEnumerator();
                        return ThisAsIEnumerator.MoveNext();
                    }
                    else { // outer cannot advance, this is the end
                        return false;
                    }
                }
    
                void IEnumerator.Reset() {
                    InternalCleanUp();
                    InternalInit();
                }
                #endregion
    
                #region methods private
                // helper properties to retrieve an explicit interface-casted this
                private IEnumerator ThisAsIEnumerator => this;
                private IEnumerator<T> ThisAsTypedIEnumerator => this;
    
                private void InternalInit() {
                    var filterBuilder = new FilterDefinitionBuilder<T>();
                    _cursor = _collection.Find(filterBuilder.Empty).ToCursor();
                }
    
                private void InternalCleanUp() {
                    if (_currentBatchEnumerator != null) {
                        _currentBatchEnumerator.Reset();
                        _currentBatchEnumerator = null;
                    }
    
                    if (_cursor != null) {
                        _cursor.Dispose();
                        _cursor = null;
                    }
                }
                #endregion
    
                #region IDisposable implementation
                private bool disposedValue = false; // To detect redundant calls
    
                private void InternalDispose(bool disposing) {
                    if (!disposedValue) {
                        if (disposing) {
                            InternalCleanUp();
    
                            _collection = null;
                        }
    
                        disposedValue = true;
                    }
                }
    
                void IDisposable.Dispose() {
                    InternalDispose(true);
                }
                #endregion
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多