Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions docs/docs/multimodal-table/global-index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,34 @@ database exists and that SQL uses that database. Load data before building index

`global-index.enabled` defaults to `true`; setting it does not create index files.

Index declarations and field options use the same configuration names as
[primary-key indexes](../primary-key-table/global-index#options):

```properties
global-index.btree.index-columns=category
global-index.ivf-pq.index-columns=embedding
ivf-pq.dimension=768
fields.embedding.index-options={"nlist":64,"distance.metric":"cosine"}
```

For raw vector searches without existing index files, declare the implementation
with `global-index.<type>.index-columns` (or singular `index-column`). The former
`index_type`, `index-type`, `vector.index-type`, and `fields.<column>.index-type`
table/query option aliases are no longer interpreted. Legacy primary-key index
configuration remains supported, including `fields.<column>.pk-vector.index.type`.

Use the actual implementation identifier, such as `ivf-pq`, in the declaration.
Each listed column declares an independent index. The singular `index-column`
spelling remains an alias; `index-columns` takes precedence. Field JSON options
override implementation-level parameters and support short keys without repeating
the implementation prefix. Existing flat vector field options such as
`fields.embedding.dimension` and `fields.embedding.nlist` remain supported.

These declarations do not schedule builds in standalone Paimon. Continue to use
the [index build commands](./global-index/manage-indexes#build-an-index), or the
index scheduling service provided by your catalog. Data Evolution indexes address
table-wide row IDs; primary-key indexes retain their bucket-local compaction lifecycle.

The example table below is shared by the BTree, Bitmap, Multivalue, Vector, and
Full-Text guides. It contains three-dimensional sample vectors and is partitioned
by `dt`, so the partition-scoped build and drop examples also apply. Create and
Expand Down
10 changes: 6 additions & 4 deletions docs/docs/multimodal-table/global-index/fm.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ choose a suitable [search mode](./manage-indexes#coverage-and-freshness).
The [visibility callback](./manage-indexes#wait-for-index-visibility) can wait for
a separate index-building job to cover committed data; it does not build indexes.

For a primary-key table, configure `pk-fm.index.columns` instead. Primary-key FM indexes follow
For a primary-key table, declare `global-index.fm.index-columns` to enable index maintenance.
Primary-key FM indexes follow
data compaction and scan uncovered files through the ordinary data path, so partial coverage does
not make `CONTAINS` results incomplete. See [Primary-Key Indexes](../../primary-key-table/global-index).

Expand All @@ -88,9 +89,10 @@ CALL sys.drop_global_index(

## Options

Global options can be passed to `create_global_index`. For a primary-key index, place the same
keys in `fields.<column>.pk-fm.index.options`; the `fm-index.` prefix may be omitted inside that
JSON object.
Global options can be passed to `create_global_index`. Both Data Evolution and primary-key
indexes accept field overrides in `fields.<column>.index-options`; the `fm-index.` prefix may
be omitted inside that JSON object. The legacy `fields.<column>.pk-fm.index.options` remains
supported when the shared field option is absent.

| Option | Default | Description |
|---|---|---|
Expand Down
105 changes: 53 additions & 52 deletions docs/docs/primary-key-table/global-index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ FM performs exact substring matching without a configured gram size and accepts
byte length. Vector and Full Text expose dedicated ranked-search APIs in Spark, Flink, and Java.
Full Text uses the fixed `full-text` implementation; Vector uses the configured ANN implementation.

Different columns in one table can use different index families. One column can occur in at most
one of `pk-vector.index.columns`, `pk-full-text.index.columns`, `pk-btree.index.columns`,
`pk-bitmap.index.columns`, `pk-multivalue.index.columns`, and `pk-fm.index.columns`.
Different columns in one table can use different index families. A primary-key table column can
occur in at most one `global-index.<type>.index-columns` declaration, including declarations
for different ANN implementations.

## Requirements

Expand All @@ -76,8 +76,9 @@ All primary-key indexes require:
- `pk-clustering-override = false`.
- An indexed column supported by the selected index implementation.

Dynamic-bucket tables, append-only tables, compound indexes, and custom index families are not
supported by this configuration.
Primary-key index maintenance does not support dynamic-bucket tables, compound indexes, or
custom index families. Data Evolution append tables share the configuration names and use
their independent [global-index build lifecycle](../multimodal-table/global-index).

<Tabs groupId="primary-key-index-requirements">

Expand Down Expand Up @@ -142,7 +143,7 @@ CREATE TABLE indexed_orders (
) WITH (
'bucket' = '8',
'deletion-vectors.enabled' = 'true',
'pk-btree.index.columns' = 'amount'
'global-index.btree.index-columns' = 'amount'
);
```

Expand All @@ -158,7 +159,7 @@ TBLPROPERTIES (
'primary-key' = 'id',
'bucket' = '8',
'deletion-vectors.enabled' = 'true',
'pk-btree.index.columns' = 'amount'
'global-index.btree.index-columns' = 'amount'
);
```

Expand Down Expand Up @@ -200,20 +201,19 @@ CREATE TABLE items (
) WITH (
'bucket' = '8',
'deletion-vectors.enabled' = 'true',
'pk-vector.index.columns' = 'embedding',
'fields.embedding.pk-vector.index.type' = 'ivf-flat',
'fields.embedding.pk-vector.distance.metric' = 'cosine',
'fields.embedding.pk-vector.index.options' = '{"nlist":"256"}',
'pk-full-text.index.columns' = 'content',
'fields.content.pk-full-text.index.options' = '{"tokenizer":"jieba"}',
'pk-fm.index.columns' = 'raw_text',
'fields.raw_text.pk-fm.index.options' = '{"partition-row-count":"100000"}',
'pk-btree.index.columns' = 'amount',
'fields.amount.pk-btree.index.options' = '{"block-size":"64 kb"}',
'pk-bitmap.index.columns' = 'status',
'fields.status.pk-bitmap.index.options' = '{"dictionary-block-size":"16 kb"}',
'pk-multivalue.index.columns' = 'tags',
'fields.tags.pk-multivalue.index.options' = '{"dictionary-block-size":"16 kb"}'
'global-index.ivf-flat.index-columns' = 'embedding',
'ivf-flat.distance.metric' = 'cosine',
'fields.embedding.index-options' = '{"nlist":"256"}',
'global-index.full-text.index-columns' = 'content',
'fields.content.index-options' = '{"tokenizer":"jieba"}',
'global-index.fm.index-columns' = 'raw_text',
'fields.raw_text.index-options' = '{"partition-row-count":"100000"}',
'global-index.btree.index-columns' = 'amount',
'fields.amount.index-options' = '{"block-size":"64 kb"}',
'global-index.bitmap.index-columns' = 'status',
'fields.status.index-options' = '{"dictionary-block-size":"16 kb"}',
'global-index.multivalue.index-columns' = 'tags',
'fields.tags.index-options' = '{"dictionary-block-size":"16 kb"}'
);
```

Expand All @@ -239,57 +239,58 @@ TBLPROPERTIES (
'primary-key' = 'id',
'bucket' = '8',
'deletion-vectors.enabled' = 'true',
'pk-vector.index.columns' = 'embedding',
'fields.embedding.pk-vector.index.type' = 'ivf-flat',
'fields.embedding.pk-vector.distance.metric' = 'cosine',
'fields.embedding.pk-vector.index.options' = '{"nlist":"256"}',
'pk-full-text.index.columns' = 'content',
'fields.content.pk-full-text.index.options' = '{"tokenizer":"jieba"}',
'pk-fm.index.columns' = 'raw_text',
'fields.raw_text.pk-fm.index.options' = '{"partition-row-count":"100000"}',
'pk-btree.index.columns' = 'amount',
'fields.amount.pk-btree.index.options' = '{"block-size":"64 kb"}',
'pk-bitmap.index.columns' = 'status',
'fields.status.pk-bitmap.index.options' = '{"dictionary-block-size":"16 kb"}',
'pk-multivalue.index.columns' = 'tags',
'fields.tags.pk-multivalue.index.options' = '{"dictionary-block-size":"16 kb"}'
'global-index.ivf-flat.index-columns' = 'embedding',
'ivf-flat.distance.metric' = 'cosine',
'fields.embedding.index-options' = '{"nlist":"256"}',
'global-index.full-text.index-columns' = 'content',
'fields.content.index-options' = '{"tokenizer":"jieba"}',
'global-index.fm.index-columns' = 'raw_text',
'fields.raw_text.index-options' = '{"partition-row-count":"100000"}',
'global-index.btree.index-columns' = 'amount',
'fields.amount.index-options' = '{"block-size":"64 kb"}',
'global-index.bitmap.index-columns' = 'status',
'fields.status.index-options' = '{"dictionary-block-size":"16 kb"}',
'global-index.multivalue.index-columns' = 'tags',
'fields.tags.index-options' = '{"dictionary-block-size":"16 kb"}'
);
```

</TabItem>

</Tabs>

Duplicate, empty, unknown, unsupported, or cross-family duplicate columns are rejected during
schema validation.

</details>

### Options

| Option | Default | Description |
|---|---|---|
| `pk-vector.index.columns` | Not set | Vector column to index. Exactly one vector column is currently supported. |
| `fields.<column>.pk-vector.index.type` | Required | ANN implementation, such as `ivf-flat`, `ivf-pq`, `ivf-sq`, `ivf-rq`, or `diskann`. |
| `fields.<column>.pk-vector.distance.metric` | `inner_product` | Distance metric: `l2`, `cosine`, or `inner_product`. |
| `fields.<column>.pk-vector.index.options` | Not set | JSON object containing build options for the selected ANN implementation. |
| `pk-full-text.index.columns` | Not set | Character column to index. Exactly one full-text column is currently supported. |
| `fields.<column>.pk-full-text.index.options` | Not set | JSON object containing native analyzer options. Unqualified keys are scoped to `full-text`. |
| `pk-fm.index.columns` | Not set | Comma-separated character columns which own independent exact FM indexes. |
| `fields.<column>.pk-fm.index.options` | Not set | JSON object containing FM build and read options. Unqualified keys are scoped to `fm-index`. |
| `pk-btree.index.columns` | Not set | Comma-separated columns which own independent BTree indexes. |
| `fields.<column>.pk-btree.index.options` | Not set | JSON object containing BTree build options. Unqualified keys are scoped to `btree-index`. |
| `pk-bitmap.index.columns` | Not set | Comma-separated columns which own independent Bitmap indexes. |
| `fields.<column>.pk-bitmap.index.options` | Not set | JSON object containing Bitmap build options. Unqualified keys are scoped to `bitmap-index`. |
| `pk-multivalue.index.columns` | Not set | Comma-separated `ARRAY` columns which own independent Multivalue indexes. |
| `fields.<column>.pk-multivalue.index.options` | Not set | JSON object containing Multivalue build options. Unqualified keys are scoped to `multivalue-index`. |
| `global-index.<type>.index-columns` | Not set | Comma-separated columns, each owning an independent index. Types include `btree`, `bitmap`, `multivalue`, `fm`, `full-text`, and actual ANN implementations such as `ivf-flat`, `ivf-pq`, `ivf-sq`, `ivf-rq`, or `diskann`. |
| `fields.<column>.index-options` | Not set | JSON object of field overrides. Short keys are scoped to the selected implementation; for example, `{"nlist":64,"distance.metric":"cosine"}` for IVF-PQ. |
| `<type>.dimension` | Implementation default | Vector dimension for the selected ANN implementation. A fixed-length `VECTOR` column also carries its dimension in the schema. |
| `<type>.distance.metric` | `inner_product` | Vector distance metric: `l2`, `cosine`, or `inner_product`. Field overrides take precedence. |
| `multivalue-index.dictionary-block-size` | `16 kb` | Target dictionary block size. |
| `multivalue-index.compression` | `none` | Dictionary-block compression algorithm. |
| `multivalue-index.compression-level` | `1` | Dictionary-block compression level. |
| `global-index.search-mode` | Not set | Legacy fallback search mode. Family-specific options take precedence. |
| `vector-index.search-mode` | `fast` | Search mode for primary-key Vector queries. `full` and `detail` search uncovered files exactly. |
| `full-text-index.search-mode` | `fast` | Search mode for primary-key Full Text queries. Only `fast` is currently supported. |

The plural `index-columns` spelling takes precedence over the singular
`global-index.<type>.index-column` alias. Both take precedence over legacy
`pk-<family>.index.columns` declarations. For legacy Vector configurations,
`pk-vector.index.columns` and `fields.<column>.pk-vector.index.type` remain supported;
a declaration such as `global-index.ivf-pq.index-columns` supplies the implementation
directly and takes precedence over the legacy Vector declaration.

Legacy `fields.<column>.pk-<family>.index.options` and
`fields.<column>.pk-vector.distance.metric` remain supported. When present,
`fields.<column>.index-options` replaces the legacy JSON option object. Its values
override existing field parameters such as `fields.embedding.nlist`, then
implementation-level defaults such as `ivf-pq.nlist`. Short JSON keys use
`btree-index.`, `bitmap-index.`, `multivalue-index.`, `fm-index.`,
`full-text.`, or the actual ANN implementation prefix.

For algorithm-specific options, see the corresponding
[BTree](../multimodal-table/global-index/btree),
[Bitmap](../multimodal-table/global-index/bitmap),
Expand Down
66 changes: 30 additions & 36 deletions docs/generated/core_configuration.html
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,18 @@
<td><p>Enum</p></td>
<td>Search mode for full-text index queries.<br /><br />Possible values:<ul><li>"fast": Only search indexed data.</li><li>"full": Use snapshot next row id and global index coverage to detect missing row ids, and scan raw data only when a gap exists.</li><li>"detail": Scan data files to find exact unindexed rows. This can handle index invalidation caused by updates or rewrites.</li></ul></td>
</tr>
<tr>
<td><h5>global-index.bitmap.index-columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated columns to index with Bitmap indexes.</td>
</tr>
<tr>
<td><h5>global-index.btree.index-columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated columns to index with BTree indexes.</td>
</tr>
<tr>
<td><h5>global-index.build.max-parallelism</h5></td>
<td style="word-wrap: break-word;">4096</td>
Expand Down Expand Up @@ -908,6 +920,24 @@
<td>Boolean</td>
<td>Whether a vector, hybrid or full-text search may read the filter columns of candidate rows to verify a row filter that the scalar global index can only answer with a superset, such as contains, ends-with or like on a BTree index or a conjunction with a member no index can evaluate. When false, such candidates are excluded from the search, which never returns a non-matching row but may return fewer than the requested top-k. When true, the read runs on the caller and may cover every candidate row.</td>
</tr>
<tr>
<td><h5>global-index.fm.index-columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated character columns to index with FM indexes.</td>
</tr>
<tr>
<td><h5>global-index.full-text.index-columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated character columns to index with full-text indexes.</td>
</tr>
<tr>
<td><h5>global-index.multivalue.index-columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated ARRAY columns to index with Multivalue indexes.</td>
</tr>
<tr>
<td><h5>global-index.query-in-reader.enabled</h5></td>
<td style="word-wrap: break-word;">false</td>
Expand Down Expand Up @@ -1386,48 +1416,12 @@
<td>String</td>
<td>You can specify a pattern to get a timestamp from partitions. The formatter pattern is defined by 'partition.timestamp-formatter'.<ul><li>By default, read from the first field.</li><li>If the timestamp in the partition is a single field called 'dt', you can use '$dt'.</li><li>If it is spread across multiple fields for year, month, day, and hour, you can use '$year-$month-$day $hour:00:00'.</li><li>If the timestamp is in fields dt and hour, you can use '$dt $hour:00:00'.</li></ul></td>
</tr>
<tr>
<td><h5>pk-bitmap.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated columns indexed by primary-key Bitmap indexes.</td>
</tr>
<tr>
<td><h5>pk-btree.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated columns indexed by primary-key BTree indexes.</td>
</tr>
<tr>
<td><h5>pk-clustering-override</h5></td>
<td style="word-wrap: break-word;">false</td>
<td>Boolean</td>
<td>Enables clustering by non-primary key fields. When set to true, the physical sort order of data files is determined by the configured 'clustering.columns' instead of the primary key, optimizing query performance for non-PK columns.</td>
</tr>
<tr>
<td><h5>pk-fm.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated character columns indexed by primary-key FM indexes.</td>
</tr>
<tr>
<td><h5>pk-full-text.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated character columns indexed by primary-key full-text indexes. The first release supports exactly one column.</td>
</tr>
<tr>
<td><h5>pk-multivalue.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated ARRAY columns indexed by primary-key Multivalue indexes.</td>
</tr>
<tr>
<td><h5>pk-vector.index.columns</h5></td>
<td style="word-wrap: break-word;">(none)</td>
<td>String</td>
<td>Comma-separated VECTOR columns indexed by primary-key vector indexes. Each column owns one index and must define fields.&lt;column&gt;.pk-vector.index.type. Index options and distance metric are also field-scoped. The first release supports exactly one column.</td>
</tr>
<tr>
<td><h5>postpone.batch-write-fixed-bucket</h5></td>
<td style="word-wrap: break-word;">true</td>
Expand Down
Loading
Loading