Creating and Deploying Indexes
-
This article explains how to create indexes in RavenDB.
For a general overview of indexes, see What are indexes. -
You can either:
- create a Static-index yourself, which involves Defining the index and Deploying it to the RavenDB server, or
- let the RavenDB server create an Auto-index for you based on query patterns.
-
Static-indexes can be created:
- using the Client API, as outlined in this article, or
- from the Indexes list view in the Studio.
Define a static-index
Static-indexes
- Indexes that are explicitly created by the user are called
static
indexes. - Static-indexes can perform calculations, data conversions, and other processes behind the scenes.
This reduces the workload at query time by offloading these costly operations to the indexing phase. - To query with a static-index, you must explicitly specify the index in the query definition.
For more details, see Querying an index.
Define a static-index using a custom class
- To define a static-index using a custom class, extend the
AbstractJavaScriptIndexCreationTask
class. - This method is recommended over the Creating an index using an operation method
for its simplified index definition, offering a straightforward way to define the index.class Orders_ByTotal extends AbstractJavaScriptIndexCreationTask { /// ... }
- A complete example of creating a static-index is provided below.
Naming convention
- Static-index class names follow a single naming convention:
Each_
in the class name is translated to/
in the index name on the server. - In the above example, the index class name is
Orders_ByTotal
.
The name of the index that will be generated on the server will be:Orders/ByTotal
.
Customizing configuration
- You can set various indexing configuration values within the index definition.
- Setting a configuration value within the index will override the matching indexing configuration values set at the server or database level.
class Orders_ByTotal extends AbstractJavaScriptIndexCreationTask { constructor() { super(); // ... // Set an indexing configuration value for this index: this.configuration = { "Indexing.MapTimeoutInSec": "30", } } }
Deploy a static-index
- To begin indexing data, the index must be deployed to the server.
- This section provides options for deploying indexes that inherit from
AbstractJavaScriptIndexCreationTask
. - To create and deploy an index using the
IndexDefinition
class viaPutIndexesOperation
,
see Creating a static-index - using an Operation.
Deploy single index
- Use
execute()
orexecuteIndex()
to deploy a single index. - The following examples deploy index
Ordes/ByTotal
to the default database defined in your DocumentStore object. See the syntax section below for all available overloads.
// Call 'execute' directly on the index instance
await new Orders_ByTotal().execute(documentStore);
// Call 'executeIndex' on your store object
await documentStore.executeIndex(new Orders_ByTotal());
Deploy multiple indexes
- Use
executeIndexes()
orIndexCreation.createIndexes()
to deploy multiple indexes. - The
IndexCreation.createIndexes
method attempts to create all indexes in a single request.
If it fails, it will repeat the execution by calling theexecute
method for each index, one by one,
in separate requests. - The following examples deploy indexes
Ordes/ByTotal
andEmployees/ByLastName
to the default database defined in your DocumentStore object.
See the syntax section below for all available overloads.
const indexesToDeploy = [new Orders_ByTotal(), new Employees_ByLastName()];
// Call 'executeIndexes' on your store object
await documentStore.executeIndexes(indexesToDeploy);
const indexesToDeploy = [new Orders_ByTotal(), new Employees_ByLastName()];
// Call the static method 'createIndexes' on the IndexCreation class
await IndexCreation.createIndexes(indexesToDeploy, documentStore);
Deploy syntax
// Call this method directly on the index instance
execute(store);
execute(store, conventions)>;
execute(store, conventions, database);
// Call these methods on the store object
executeIndex(index);
executeIndex(index, database);
executeIndexes(indexes);
executeIndexes(indexes, database);
// Call these methods on the IndexCreation class
createIndexes(indexes, store);
createIndexes(indexes, store, conventions);
Parameter | Type | Description |
---|---|---|
store | object |
Your document store object. |
conventions | DocumentConventions |
The Conventions used by the document store. |
database | string |
The target database to deploy the index to. If not specified, the default database set on the store will be used. |
index | object |
The index object to deploy. |
indexes | object[] |
A list of index objects to deploy. |
Deployment behavior
Deployment mode:
- When your database spans multiple nodes,
you can choose between Rolling index deployment or Parallel index deployment. - Rolling deployment applies the index to one node at a time,
while Parallel deployment deploys the index on all nodes simultaneously. - Learn more in Rolling index deployment.
When the index you are deploying already exists on the server:
-
If the index definition is updated:
- RavenDB uses a side-by-side strategy for all index updates.
- When an existing index definition is modified, RavenDB creates a new index with the updated definition. The new index will replace the existing index once it becomes non-stale.
- If you want to swap the indexes immediately, you can do so through the Studio.
For more details, see Side by side indexing.
-
If the index definition is unchanged:
- If the definition of the index being deployed is identical to the one on the server,
the existing index will not be overwritten. - The indexed data will remain intact, and the indexing process will not restart.
- If the definition of the index being deployed is identical to the one on the server,
Create a static-index - Example
// Define a static-index:
// ======================
class Orders_ByTotal extends AbstractJavaScriptIndexCreationTask {
constructor() {
super();
this.map("Orders", order => {
return {
Employee: order.Employee,
Company: order.Company,
Total: order.Lines.reduce((sum, line) =>
sum + (line.Quantity * line.PricePerUnit) * (1 - line.Discount), 0)
}
});
// Customize the index configuration
this.deploymentMode = "Rolling";
this.configuration["Indexing.MapTimeoutInSec"] = "30";
this.indexes.add(x => x.Company, "Search");
// ...
}
}
async function main() {
const documentStore = new DocumentStore("http://localhost:8080", "Northwind");
documentStore.initialize();
// Deploy the index:
// =================
const ordersByTotalIndex = new Orders_ByTotal();
await ordersByTotalIndex.execute(documentStore);
const session = documentStore.openSession()
// Query the index:
// ================
const myIndexName = ordersByTotalIndex.getIndexName();
const orders = await session
.query({ indexName: myIndexName })
.whereGreaterThan("Total", 100)
.all();
}
Create a static-index - using an Operation
-
An index can also be defined and deployed using the PutIndexesOperation maintenance operation.
-
When using this operation:
-
Unlike the naming convention used with indexes inheriting from
AbstractJavaScriptIndexCreationTask
,
you can choose any string-based name for the index.
However, when querying, you must use that string-based name rather than the index class type. -
You can also modify various low-level settings available in the IndexDefinition class.
-
-
Consider using this operation only if inheriting from
AbstractJavaScriptIndexCreationTask
is not an option. -
For a detailed explanation and examples, refer to the dedicated article: Put Indexes Operation.
Creating auto-indexes
Auto-indexes creation
- Indexes created by the server are called
dynamic
orauto
indexes. -
Auto-indexes are created when all of the following conditions are met:
- A query is issued without specifying an index (a dynamic query).
- The query includes a filtering condition.
- No suitable auto-index exists that can satisfy the query.
- Creation of auto-indexes has not been disabled.
- For such queries, RavenDB's Query Optimizer searches for an existing auto-index that can satisfy the query. If no suitable auto-index is found, RavenDB will either create a new auto-index or optimize an existing auto-index. (Static-indexes are not taken into account when determining which auto-index should handle the query).
- Note: dynamic queries can be issued either when querying or when patching.
- Over time, RavenDB automatically adjusts and merges auto-indexes to efficiently serve your queries.
For more details, see Query a collection - with filtering (dynamic query).
Naming convention
- Auto-indexes are easily identified by their names, which start with the
Auto/
prefix. - Their name also includes the name of the queried collection and a list of fields used in the query predicate to filter matching results.
- For example, issuing the following query:
const employees = await session .query({ collection: 'employees' }) .whereEquals("FirstName", "Robert") .whereEquals("LastName", "King") .all();
from Employees where FirstName = "Robert" and LastName = "King"
Auto/Employees/ByFirstNameAndLastName
.
Auto-index idle state
- To reduce server load, an auto-index is marked as
idle
when it hasn't been used for a while.
Specifically, if the time difference between the last time the auto-index was queried and the last time a query was made on the database (using any index) exceeds the configured threshold (30 minutes by default), the auto-index will be marked asidle
. - This is done in order to avoid marking indexes as idle for databases that were offline for a long period of time, as well as for databases that were just restored from a snapshot or a backup.
- To set the time before marking an index as idle, use the
Indexing.TimeToWaitBeforeDeletingAutoIndexMarkedAsIdleInHrs configuration key.
Setting this value too high is not recommended, as it may lead to performance degradation by causing unnecessary and redundant work for the indexes. - An
idle
auto-index will resume its work and return tonormal
state upon its next query,
or when resetting the index. - If not resumed, the idle auto-index will be deleted by the server after the time period defined in the
Indexing.TimeToWaitBeforeDeletingAutoIndexMarkedAsIdleInHrs configuration key
(72 hours by default).
Disabling auto-indexes
Why disable:
- Disabling auto-index creation prevents the accidental deployment of resource-consuming auto-indexes that may result from one-time, ad-hoc queries issued from the Studio.
- In production environments, disabling this feature helps avoid the creation and background execution of expensive indexes.
How to disable:
-
You can disable auto-indexes by setting the Indexing.DisableQueryOptimizerGeneratedIndexes configuration key. This will affect all queries made both from the Client API and the Studio.
-
Alternatively, you can disable auto-indexes from the Studio.
However, this will affect queries made only from the Studio.- To disable auto-index creation for a specific query made from the query view, see these Query settings.
- To disable auto-index creation for a specific query made from the patch view, see these Patch settings.
- Disabling auto-index creation for ALL queries made on a database can be configured in the Studio configuration view.