Indexes
RethinkDB supports four kinds of secondary indexes:
- Simple indexes based on the value of a single field.
- Compound indexes based on multiple fields.
- Multi indexes based on arrays of values.
- Indexes based on arbitrary expressions.
NoBrainer provides methods to declare indexes which can then be leveraged when generating queries as RethinkDB does not use indexes automatically.
Declaring Indexes
Using Indexes
Because RethinkDB requires explicit index usage, NoBrainer tries to leverage indexes to compile efficient queries implicitly. For example:
Because of the implicit/explicit usage of indexes, NoBrainer does not allow a compound or arbitrary index to have the same name as a regular field. Otherwise, the query would be ambiguous: would we be filtering on the field or the index?
criteria.order_by()
will also try to use an index for efficiency. NoBrainer
will try to use an index only on the first ordering clause.
When compiling a query, NoBrainer may have multiple possibilities to pick which
index to use. When not sure, NoBrainer will pick the first declared index in the model.
You may manually sepecify which index to use by criteria with with_index(index_name)
.
This forces NoBrainer to use the given index when compiling the query.
An error NoBrainer::Error::CannotUseIndex
will be raised if the provided index
cannot be used. You may also chain without_index
to disable the usage of
indexes all together.
You may also use with_index()
without arguments. In this case, an exception
is raised if NoBrainer cannot find an index to use when compiling the query.
The latest with_index()
in the query wins.
Testing Indexes
To test your code and do some profiling, you may use criteria.used_index
to get the
name of the index that will be used for the query. You may also use
criteria.where_indexed?
or criteria.order_by_indexed?
to test if an index is used. Note that these methods applies the default scope
before returning an answer.
Creating Indexes
Once declared, indexes need to be created before being usable.
When using Rails, you may use the rake task:
You can also update indexes programmatically:
NoBrainer maintains a list of index metadata in a table named nobrainer_index_meta
.
This way, NoBrainer can keep track of the indexes state on the database, and update
indexes which definition have changed.
NoBrainer waits for the index creation by default.
You may pass :wait => false
to sync_schema
to skip the wait.
Aliases
An alias can be specified on a given index as such:
NoBrainer will translate all the references to that index when compiling queries and reading models back from the database.
The only place you need to be careful is when using RQL, including passing RQL lambda. NoBrainer does not translate aliases with user provided RQL code.
External Indexes
If you prefer to manage certain indexes yourself, you may declare them as external as such:
NoBrainer does not touch external indexes when synchronizing indexes.
Reflection
You may go through the list of declared indexes on a model by looking up the
hash Model.indexes
of the form {:index_name => index}
.
index.kind
is the kind of index which can be :single
, :compound
, or :proc
.
index.what
is the indexed value which is the field name, field names, or proc depending if the index kind is a single, compound, or proc, respectively.
index.multi
is a boolean indicating whether the index is a multi index.
index.geo
is a boolean indicating whether the index is a geo index.