This feature is in and subject to change. To share feedback and/or issues, contact Support.
LTREE stores hierarchical tree-like structures as a label path, which is a sequence of dot-separated labels. Labels represent positions in a tree hierarchy. LTREE is useful for efficiently querying and managing hierarchical data without using recursive joins.
Syntax
Each label in anLTREE label path represents a level in the hierarchy, beginning from the root (Animals in the following example):
A-Z, a-z, 0-9), underscores (_), and hyphens (-). The maximum label length is 1,000 characters, and the maximum number of labels in a path is 65,535.
The following are valid LTREE values:
'Animals''Products.Electronics.Laptops.Gaming''project_a.phase-1.task_001'''(empty path)
Size
The size of anLTREE value is variable and equals the total number of characters in all labels plus the total number of dot separators. Cockroach Labs recommends keeping values below 64 kilobytes. Above that threshold, and other considerations may cause significant performance degradation.
Operators
The followingLTREE comparison and containment operators are valid:
=(equals). Compare paths for equality.<>,!=(not equal to). Compare paths for inequality.<,<=,>,>=(ordering). Compare paths lexicographically.@>(is ancestor of). Returnstrueif the left operand is an ancestor of (or equal to) the right operand.<@(is descendant of). Returnstrueif the left operand is a descendant of (or equal to) the right operand.||(concatenate). Concatenate twoLTREEpaths.
LTREE arrays, the following operators return the first matching element:
?@>(array contains ancestor). Returns the first array element that is an ancestor of the operand.?<@(array contains descendant). Returns the first array element that is a descendant of the operand.
Index acceleration
CockroachDB supports indexingLTREE columns. on LTREE columns accelerate the following operations:
- Comparison operators:
=,<>,!=,<,<=,>,>= - Containment operators:
@>,<@
Functions
The following are supported forLTREE:
| Function | Description |
|---|---|
index(a ltree, b ltree [, offset]) | Returns the position of the first occurrence of b in a, optionally starting at offset. Returns -1 if not found. |
lca(ltree, ltree, ...) | Returns the longest common ancestor (longest common prefix) of the paths. Accepts unlimited arguments or an array. |
ltree2text(ltree) | Converts an LTREE value to STRING. |
nlevel(ltree) | Returns the number of labels in the path. |
subltree(ltree, start, end) | Extracts a subpath from position start to position end-1 (zero-indexed). |
subpath(ltree, offset [, length]) | Extracts a subpath starting at offset. If offset is negative, starts that far from the end. Optional length specifies how many labels to include. |
text2ltree(text) | Converts a STRING value to LTREE. |
Supported casting and conversion
You canLTREE values to the following data type:
Examples
Create a table with hierarchical data
Create a table to store an organizational hierarchy:Query LTREE with comparison operator
Find all entries that come before Studio.ShowB using lexicographic ordering. The < operator returns entries where the path is lexicographically less than Studio.ShowB:
Query LTREE with containment operator
Find all entries under Show A using the <@ (is descendant of) operator:
Episode 1 in Show A using the @> (is ancestor of) operator:
Use LTREE functions
Count the depth level of each entry using nlevel():
subpath(), with an offset of 1:
LTREE values using lca():
Concatenate two LTREE values
Build paths dynamically by concatenating two LTREE values using the || operator:

