Skip to content

Indexing

Overview

This page describes how to create and manage secondary indexes (sindexes). Indexes can make graph database queries faster and more efficient.

There are two ways to create sindexes:

You can then manage indexes with the call API.

Secondary indexes speed up traversals because they apply only to the first step. When a traversal begins with filters on both an indexed and a non-indexed property, AGS evaluates the indexed filter first. You get the most benefit by indexing high-cardinality properties that sharply reduce the candidate set. Property indexes typically provide more selectivity than label indexes, so starting the traversal at a property index is often the most efficient path.

Create an index with the call API

AGS supports typed vertex property sindexes. Use index_type to create either a string or numeric index. Typed indexes reduce memory consumption in the Aerospike database.

If you do not specify index_type, AGS creates both string and numeric indexes. If only one type exists, AGS creates the missing type.

Create a typed vertex property sindex

g.call("aerospike.graph.admin.index.create").
with("element_type", "vertex").
with("property_key", "name").
with("index_type", "string").next()
g.call("aerospike.graph.admin.index.create").
with("element_type", "vertex").
with("property_key", "age").
with("index_type", "numeric").next()

Expected output:

Vertex index creation of property key 'name' in progress.
  • property_key is the name of the property you want to index.
  • You can index any user-defined property or the ~label field. The ~id field is indexed automatically.

Create a vertex label index

g.call("aerospike.graph.admin.index.create").
with("element_type", "vertex").
with("property_key", "~label").next()

Creation without index_type for both types

The following example creates both string and numeric indexes because index_type is not set.

g.call("aerospike.graph.admin.index.create").
with("element_type", "vertex").
with("property_key", "name").next()

Create an index with configuration

You can create indexes by configuration when starting AGS in Docker.

Typed vertex property index creation

AGS supports typed configuration keys. Provide property keys as a comma-separated list.

Terminal window
aerospike.graph.index.vertex.properties.string=name,city
aerospike.graph.index.vertex.properties.numeric=age,salary

Vertex label index creation

Enable a label index for all vertex labels:

Terminal window
aerospike.graph.index.vertex.label.enabled=true

If you create a label index on one AGS instance, other instances in the cluster detect and use it.

Configuration without index_type for both types

The legacy key creates both numeric and string indexes for the listed properties.

Terminal window
aerospike.graph.index.vertex.properties=property_key1,property_key2

Vertex property indexes are taken as a union from all AGS instances. If one instance has an index on property_key1 and another has an index on property_key2, AGS creates and uses both.

When a vertex property index is first created on a dataset, creation time is proportional to the amount of data in the Aerospike database. Larger datasets take longer. Creating indexes before loading data is faster, but you can create them afterward as well.

Manage indexes

Use the call API to drop indexes and to view index status, existing keys, and cardinality.

Drop a secondary index

Specify index_type to drop a specific typed index, or omit it to drop both.

g.call("aerospike.graph.admin.index.drop").
with("element_type", "vertex").
with("property_key", "name").
with("index_type", "string").next()
g.call("aerospike.graph.admin.index.drop").
with("element_type", "vertex").
with("property_key", "age").
with("index_type", "numeric").next()

Omitting index_type drops both types

g.call("aerospike.graph.admin.index.drop").
with("element_type", "vertex").
with("property_key", "name").next()

Expected output:

Vertex index of property key 'name' dropped.

Index status

Get the status of a vertex property index:

g.call("aerospike.graph.admin.index.status").
with("element_type", "vertex").
with("property_key", "<key>").next()
  • percent_complete: Percentage from 0 to 100. Returns 100 when the index is ready to use.
  • total_entries: Total number of entries in the index across all Aerospike nodes.
  • total_used_bytes: Total RAM usage in bytes of the index across all Aerospike nodes.
  • load_time: Time in milliseconds to create the index.

List indexed property keys

List all property keys with existing secondary indexes:

g.call("aerospike.graph.admin.index.list").next()

If successful, AGS returns a list of indexed property keys.

Cardinality

In general, indexes with higher cardinality are more effective. To see examples of how indexes affect graph queries, see Traversals.

Get the cardinality of existing secondary indexes:

g.call("aerospike.graph.admin.index.cardinality").next()

If successful, AGS returns a list of indexed property keys and the cardinality of each one. The cardinality of an index is the number of unique entries in that index.

Traversals

Indexes apply to the first step only. When the initial steps include both indexed and non-indexed properties, AGS runs the indexed filter first. Property indexes typically have higher cardinality than label indexes.

Single indexed vertex property

This traversal uses the index on the name field:

______ The first step uses the index, so it is fast and efficient.
|
| _______________ Subsequent steps do not use
| | | | the index because they are not at the
| | | | start of the traversal.
v V v v
g.V().has("name", "Lyndon").out().in().has("name", "Simon").toList()

Single non-indexed vertex property

This traversal does not use an index and may perform poorly.

______ This step does not use an index and must scan the entire database
| for the `country` property.
|
| __________ These steps do not use the index because they
| | | are not at the start of the traversal.
v V v
g.V().has("country", "USA").out().has("name", "Lyndon").toList()

One indexed and one non-indexed vertex property

This traversal performs two has steps, one on the non-indexed country field and one on the indexed name field. AGS compounds the two has steps together and runs the indexed one first, improving performance.

g.V().has("country", "USA").has("name", "Lyndon").out().has("name", "Simon").toList()

Two indexed vertex properties

This traversal performs two initial has steps, both on indexed properties. AGS uses cardinality metadata from the Aerospike database to determine which step to run first for maximum efficiency.

g.V().has("age", 29).has("name", "Lyndon").out().has("name", "Simon").toList()

Label index and indexed vertex property

This traversal’s first two steps are a hasLabel step which uses the instance’s label index, and a has step which uses the name property index. AGS performs the has step first because property indexes usually have higher cardinality than label indexes.

g.V().hasLabel("Person").has("name", "Lyndon").out().has("name", "Simon").toList()

Label index and non-indexed vertex property

This traversal begins with a hasLabel step which uses the instance’s label index, and a has step which involves the non-indexed country property. AGS performs the hasLabel step first and uses the index, but the country step may be slow and inefficient.

g.V().hasLabel("Person").has("country", "USA").out().has("name", "Simon").toList()
Feedback

Was this page helpful?

What type of feedback are you giving?

What would you like us to know?

+Capture screenshot

Can we reach out to you?