Skip to content
Mauricio David edited this page Mar 17, 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. Without an index, LiteDB must execute a query using full document scan. This collection scans are inefficient because LiteDB must deserialize all documentto test one by one.

Index Implementation

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.

Documents are schema-less, even if they are in a same collection. So, you can create an index on a field that can be one type in a document and other type in the next document. When you have a field with different 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
  • Numbers (Int32, Int64 or Double) has same order. If you mix this numbers types in a same document field, LiteDB will convert them to Double when comparing

IndexOptions

LiteDB has some options that you can use when you are creating a new index. This options can't be modified after index created. If you chanced, 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 later 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
  • Indexes are executed in BsonDocument fields. If you are using a custom ResolvePropertyName or [BsonField] attribute, you must use your document field name and not property name. See (Object Mapping)[Object-Mapping].
  • You can use LINQ expression to define index field in strong typed collection: EnsureIndex(x => x.Name)

Limitations

  • Index value must have less than 512 bytes (after BSON serialization)
  • Max of 16 indexes per collections - including _id primary key
  • [BsonIndex] is not supported in embedded documents