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:
entityorconnection. - class: The entity or connection class.
- property: The property to index.
- kind:
ordered,trigram,similarity,fulltext,type, orarray. - 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): Supportssimilarity.case_insensitive: Supportsisimilarity.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"]