Back to top

ReQL command: indexCreate

Command syntax

table.indexCreate(indexName[, indexFunction][, {multi: false, geo: false}]) → object


Create a new secondary index on a table. Secondary indexes improve the speed of many read queries at the slight cost of increased storage space and decreased write performance. For more information about secondary indexes, read the article “Using secondary indexes in RethinkDB.”

RethinkDB supports different types 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, created when the multi optional argument is true.
  • Geospatial indexes based on indexes of geometry objects, created when the geo optional argument is true.
  • Indexes based on arbitrary expressions.

The indexFunction can be an anonymous function or a binary representation obtained from the function field of indexStatus. The function must be deterministic, and so cannot use a subquery or the r.js command.

If successful, createIndex will return an object of the form {"created": 1}. If an index by that name already exists on the table, a ReqlRuntimeError will be thrown.

Note that an index may not be immediately available after creation. If your application needs to use indexes immediately after creation, use the indexWait command to ensure the indexes are ready before use.

Example: Create a simple index based on the field postId.

r.table('comments').indexCreate('postId').run(conn, callback)

Example: Create a geospatial index based on the field location.

r.table('places').indexCreate('location', {geo: true}).run(conn, callback)

A geospatial index field should contain only geometry objects. It will work with geometry ReQL terms (getIntersecting and getNearest) as well as index-specific terms (indexStatus, indexWait, indexDrop and indexList). Using terms that rely on non-geometric ordering such as getAll, orderBy and between will result in an error.

Example: Create a simple index based on the nested field author > name.

r.table('comments').indexCreate('authorName', r.row("author")("name")).run(conn, callback)

Example: Create a compound index based on the fields postId and date.

r.table('comments').indexCreate('postAndDate', [r.row("postId"), r.row("date")]).run(conn, callback)

Example: Create a multi index based on the field authors.

r.table('posts').indexCreate('authors', {multi: true}).run(conn, callback)

Example: Create a geospatial multi index based on the field towers.

r.table('networks').indexCreate('towers', {multi: true, geo: true}).run(conn, callback)

Example: Create an index based on an arbitrary expression.

r.table('posts').indexCreate('authors', function(doc) {
    return r.branch(
}).run(conn, callback)

Example: Create a new secondary index based on an existing one.

r.table('posts').indexStatus('authors').nth(0)('function').run(conn, function (func) {
    r.table('newPosts').indexCreate('authors', func).run(conn, callback);

Example: Rebuild an outdated secondary index on a table.

r.table('posts').indexStatus('oldIndex').nth(0).do(function(oldIndex) {
  return r.table('posts').indexCreate('newIndex', oldIndex("function")).do(function() {
    return r.table('posts').indexWait('newIndex').do(function() {
      return r.table('posts').indexRename('newIndex', 'oldIndex', {overwrite: true})

Get more help

Couldn't find what you were looking for?