Skip to main content

CreateIndex

Creates and populates an index on one entity or connection property. A successful response contains status: 0. Use :doc:GetIndexes to list definitions and :doc:RemoveIndex to remove one by class, property and kind.

Parameters​

  • target: entity or connection.
  • class: The entity or connection class.
  • property: The property to index.
  • kind: ordered, trigram, similarity, fulltext, type, or array.
  • params (optional): Options for the selected kind, described below.

Class and property names are matched without case sensitivity. Each property can have at most one index of each kind. Different kinds can coexist, but creating another index of the same kind fails even when its parameters differ. Explicitly specifying default parameters is equivalent to omitting them.

Parameters cannot be changed after creation. To change them, remove the index and create a new one. Both commands can run in the same transaction. Computed properties, descriptor vector indexes, and indexes spanning multiple properties are not supported by this command.

Index kinds​

Ordered​

ordered always indexes booleans, numbers, datetimes, and strings for equality and range comparisons. Its only parameter is text: case_sensitive (default), case_insensitive, or dual_case. Type-selection parameters (bool, number, date, and text: false) are no longer accepted.

case_insensitive uses Unicode full case folding without removing accents or normalizing Unicode forms. dual_case supports both case-sensitive and case-insensitive comparisons.

Trigram​

trigram supports substring searches. Its only parameter is text, which accepts case_sensitive (default), case_insensitive, or dual_case. The case modes have the same meaning as for ordered indexes. Parameters bool, number, and date are not accepted.

Similarity​

similarity supports whole-string fuzzy matching with the similarity and isimilarity functions. Its only parameter is text:

  • case_sensitive (default): Supports similarity.
  • case_insensitive: Supports isimilarity.
  • dual_case: Supports both functions.

These functions also work without an index. A similarity index can accelerate filters that compare a stored string property with a literal string and require a positive score. Trigram indexes support substring searches, not similarity scoring.

Full text​

fulltext is required for the fulltext function, which matches words and returns BM25 relevance scores for a native string property.

The only supported parameter is {"analyzer": "unicode_v1"}, which is also the default. The analyzer applies Unicode NFKC case folding and splits text at word boundaries. See :ref:text-search for matching rules, score interpretation, and input limits.

Type​

type supports property presence and type queries. It distinguishes boolean, number, date, text, JSON, native array, and blob properties. It accepts no parameters; omit params or use {}.

JSON properties have the JSON storage type regardless of their payload. Expression functions such as is_missing and is_finite evaluate the payload's value.

A type index is optional. Ordered and trigram planning first uses existing class/property counts. When those counts are inconclusive, the value index can check its own coverage within the candidate set, provided that check is cheaper than evaluating the expression. An explicit type index remains useful for type queries and as another source of membership information. Creating or removing it does not change query results or error semantics.

Ordered and trigram indexes retain IDs of present values outside their configured native domain. Compatible values reuse existing entries; missing properties add no coverage records. Empty and short strings are native to a trigram index even when they produce no trigrams. Ordered indexes cover all native scalar types; JSON, array, and blob values use their internal nonnative coverage. Coverage is internal to that index and cannot be removed separately with RemoveIndex. See :doc:../parameters/constraints for operator coverage and eligibility.

Array​

array supports in and not_in membership filters between a native Array property and constant values or lists, with the property on either side. String membership uses exact byte matching. JSON payloads are not indexed. An array index can be created before the property contains arrays; scalar and missing values are not included.

positions is a list of zero-based element positions or the string "all" to index every position present in each array. Positions must be whole numbers between 0 and 4294967295. They are sorted and deduplicated in the returned definition. Omitting params or positions is equivalent to {"positions": []}; no positional entries are created.

Use the default empty list for membership queries. Configured positions add value and type postings for each indexed element. Type postings are enabled by default. {"positions": "all"} adds entries for every element, including repeated values, and therefore increases storage and write work in proportion to array length.

Set type_postings to false to reduce positional write and storage work, for example {"positions": "all", "type_postings": false}. Type counts and query correctness are preserved: type checks then read the typed value buckets, which can cost more for mixed-type or null queries. The default is true; normalized definitions omit this parameter when it has its default value. Membership-only indexes do not create positional type postings with either setting.

Positional entries can accelerate ==, !=, and range comparisons between at("$property", constant_position) and a constant scalar, including field-free expressions such as subtract or to_date. They also support is_missing, is_finite, and membership in a constant list. Null and Boolean values support equality and inequality, not ordering. Adjacent compatible lower and upper bounds can share one positional lookup.

All array indexes retain array presence, empty-array postings, and length summaries. These can accelerate count("$property") comparisons and whole-array equality or inequality even without configured positions. Whole-array comparisons retain structural verification of order, duplicates, and element types. A covered position can answer a length bound using its type postings; null elements count as present positions.

The planner compares bounded index-work estimates with ordinary evaluation. Small candidate sets, dense results, or small result limits can favor a scan. Type coverage is checked within the query's candidates; incompatible types or an inconclusive bounded check retain ordinary evaluation and its errors. An immediately preceding equality in an all group can fix a position field, for example ["$slot", "==", 0] followed by a comparison using at("$property", "$slot"). The equality must be safe for the stored position field; the original conditions still verify candidates in their original order. Other dynamic positions, computed arrays, and JSON payloads retain evaluation.

A small sorted page with one constant-position at expression can also use positional entries when type postings are enabled. The index retains complete boundary buckets and the ordinary sorter resolves exact values and object-ID ties. This requires native Array or missing source values. Multi-key sorts, large pages or collision buckets, and expensive access retain ordinary sorting. See :doc:../parameters/sort for details. Existing indexes must be removed and recreated to change their configured positions or type-posting setting.

Examples​


[{
"CreateIndex": {
"kind": "ordered",
"target": "entity",
"class": "Person",
"property": "name",
"params": {
"text": "dual_case"
}
}
}]

Create an index for the presence and type of an optional property:


[{
"CreateIndex": {
"kind": "type",
"target": "entity",
"class": "Person",
"property": "email",
"params": {
}
}
}]

Create a membership index for a list property:


[{
"CreateIndex": {
"kind": "array",
"target": "entity",
"class": "Palette",
"property": "colors",
"params": {"positions": []}
}
}]

The membership index can accelerate these queries:


["red", "in", "$colors"]
["$colors", "in", {"array": ["red", "blue"]}]

The following at comparison can use an array index configured with {"positions": [0]} or {"positions": "all"}:


[{"at": ["$colors", 0]}, "==", "red"]