Skip to content
Mauricio David edited this page Mar 15, 2015 · 22 revisions

LiteDB use index on document fields to do fast searches. Index stores the value of a specific field ordered by the value (and type) of the field.

LiteDB use the a simple index solution: Skip Lists. Skip list are a double linked sorted list with up to 32 levels. Skip list are super easy to implement (only 15 lines of code) and statistic balanced. The results are great: insert and find results has average of O(ln n) = 1 milion of documents = 13 steps. If you want to know more about skip list, see this great video.

At this point, all queries must have an index to be executed by LiteDB engine. But Find methods always returns an IEnumberable, so you can use LINQ to Objects to do more complex queries (using full scan on returned results). See Queries

Documents are schemeless, even if they are in a same collection. So, you can create an index on a field that can has diferent types on diferent documents. When you have fields with diferent types, LiteDB compares type only. Each type has an order:

BSON Type Order
MinValue 1
Null 2
Int32, Int64, Double 3
String 4
Document 5
Array 6
Binary 7
ObjectId 8
Guid 9
Boolean 10
DateTime 11
MaxValue 12
  • Note that numbers (Int32, Int64 or Double) has the same order. If you mix this numbers types in a document field, LiteDB will convert both to Double when comparing (not on document).
  • Every index starts with 2 elements: one with MinValue (head) and one with MaxValue (tail). All others items are sorted in the middle of this two.

Index Options

LiteDB has some options that you can use when are creating a new index. This options can't be changed after index created. If you chance, LiteDB drop current index and create a new one.

  • Unique - Defines an index that has only unique values.
  • IgnoreCase - Convert field value to lower case. (String only)
  • RemoveAccents - Remove all accents on field value (áéíóú => aeiou) (String only)
  • TrimWhitespace - Apply String.Trim() on field value. (String only)
  • EmptyStringToNull - If field value are empty convert to BsonValue.Null. (String only)

Note: all changes in index value doesn't affect document field value. This rules are applied only in value on index and on value that will be used latter on compare.

EnsureIndex

Indexes are created using EnsureIndex method in LiteCollection. This method ensure an index: create if not exists, re-create if index options are different from existing or do nothing if index already exits with same options.

Another way is use [BsonIndex] attribute on your class. This attribute will be read and runs an EnsureIndex only the first time you use in a query. For performance reason, this way do not checks only if index exists and no index options changes.

Indexes are identified by document field name. LiteDB supports only 1 field per index, but this field can be any BSON type, even an embedded document.

{
    _id: 1,
    Address:
    {
        Street: "Av. Protasio Alves, 1331",
        City: "Porto Alegre",
        Country: "Brazil"
    }
}
  • You can use EnsureIndex("Address") to create an index to all Address embedded document
  • Or EnsureIndex("Address.Street") to Street only field using dotted notation

Limitations

  • Index value must have less than 512 bytes (after BSON serialization)
  • [BsonIndex] is not supported in embedded documents
  • LINQ not support embedded documents: EnsureIndex(x => x.Address.Street) not works - use EnsureIndex("Address.Street")