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
- Reduce the source to fewer than 2000 documents before applying OrderBy/GroupBy (filter first).
- Perform the ordering/grouping in application code (LINQ) before/instead of in the LiteDB query.
- If using a real (non-virtual) collection, ensure the query uses a physical index so IndexVirtual is not used.
- 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
- Keep virtual/external sources under 2000 documents for OrderBy/GroupBy.
- Filter (Where) and paginate before ordering on virtual collections.
- Prefer real collections with physical indexes for large sorted queries.
- Sort large external sources in application code (LINQ).
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
- GROUP BY expression do not support INCLUDE
- Multiple OrderBy calls are not supported. Use ThenBy for add
- GROUP BY already defined in this query
- HAVING already defined in this query
- 0
AI-assisted analysis of litedb-org/LiteDB@f906a5f850 (2026-08-13).
Data as JSON: /api/errors/0e890d593b2bbb21.
Report an issue: GitHub.