litedb-org/LiteDB · warning · LiteException

0

0

Error message

OrderBy/GroupBy operation are supported only in virtual collection with less than {VIRTUAL_INDEX_MAX_CACHE} documents

What it means

Thrown by IndexVirtual.Load(PageAddress) when an OrderBy or GroupBy operation requires document lookup from a virtual (in-memory/external) collection, but the internal cache has been nulled because the source exceeded VIRTUAL_INDEX_MAX_CACHE (2000) documents. IndexVirtual caches source documents by rawId up to 2000 entries to support OrderBy/GroupBy lookups; past that limit the cache is dropped to bound memory, and any subsequent lookup that needs it fails.

Source

Thrown at LiteDB/Engine/Query/IndexQuery/IndexVirtual.cs:64

                {
                    _cache[rawId] = doc;

                    if (_cache.Count > VIRTUAL_INDEX_MAX_CACHE) _cache = null;
                }

                // return an fake indexNode
                yield return new IndexNode(doc);
            }
        }

        public BsonDocument Load(IndexNode node)
        {
            return node.Key as BsonDocument;
        }

        public BsonDocument Load(PageAddress rawId)
        {
            if (_cache == null) throw new LiteException(0, $"OrderBy/GroupBy operation are supported only in virtual collection with less than {VIRTUAL_INDEX_MAX_CACHE} documents");

            return _cache[rawId.PageID];
        }

        public override string ToString()
        {
            return string.Format("FULL COLLECTION SCAN");
        }
    }
}

View on GitHub (pinned to f906a5f850)

Solutions

  1. Reduce the source to fewer than 2000 documents before applying OrderBy/GroupBy (filter first).
  2. Perform the ordering/grouping in application code (LINQ) before/instead of in the LiteDB query.
  3. If using a real (non-virtual) collection, ensure the query uses a physical index so IndexVirtual is not used.
  4. Paginate the virtual source with Limit/Offset to stay under the cache threshold.

Example fix

// before — virtual source too large for ORDER BY
var docs = LoadExternalDocs(); // 5000 docs
var q = db.GetCollection("$dump").Query().OrderBy("$.name").ToEnumerable();
// throws during enumeration

// after — sort in app, or filter/paginate first
var sorted = docs.OrderBy(d => d["name"]).ToList();
// or paginate: .Limit(2000) before OrderBy
Defensive patterns

Strategy: validation

Validate before calling

const int VIRTUAL_MAX = 2000;

public List<BsonDocument> QueryExternal(LiteDatabase db, IEnumerable<BsonDocument> source)
{
    var materialized = source.Take(VIRTUAL_MAX + 1).ToList();
    if (materialized.Count > VIRTUAL_MAX)
    {
        // Source is too large for in-DB OrderBy/GroupBy — sort in app code instead.
        materialized = source.OrderBy(d => d["name"].AsString).ToList();
        return materialized;
    }
    // Safe to use virtual collection with OrderBy.
    return db.GetCollection("$dump").InsertBulk(materialized) > 0
        ? db.GetCollection("$dump").Query().OrderBy("$.name").ToList()
        : materialized;
}

Type guard

static bool IsSafeForVirtualOrderBy(IEnumerable<BsonDocument> source)
{
    // Only safe if you can cheaply count; otherwise cap with Take.
    return source.Take(2001).Count() <= 2000;
}

Try / catch

try
{
    var results = virtualQuery.OrderBy("$.name").ToList();
}
catch (LiteException ex) when (ex.Message.Contains("virtual collection with less than"))
{
    // Fall back to in-memory LINQ ordering over a materialized list.
    results = source.OrderBy(d => d["name"].AsString).ToList();
}

Prevention

When it happens

Trigger: Running a query with .OrderBy() or .GroupBy() over an external/virtual source (e.g. a system collection, a $dump, or a manually-supplied IEnumerable<BsonDocument> in IndexVirtual) that yields more than 2000 documents. The cache is discarded after the 2000th document; a later OrderBy/GroupBy phase triggers Load(PageAddress) and throws.

Common situations: Sorting or grouping large in-memory result sets passed as an external source; querying system collections ($dump, $sequences) with ORDER BY over more than 2000 rows; using ILiteCollection.Query over a virtual source.

Related errors


AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13). Data as JSON: /api/errors/0e890d593b2bbb21. Report an issue: GitHub.