Lance FTS V3 Term Spaces #6959
Xuanwo
started this conversation in
Lance Table Format
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Abstract
This document proposes introducing FTS V3: retain V2 default behaviors and the existing tokenizer parameter model, while adding minimal format capabilities to support future multiple term spaces.
V3 continues to use the current tokenizer, filters, scoring, and query semantics by default. The first goal of V3 is to keep the single-space path close to V2, while allowing the format to express multiple independent statistical spaces when needed.
Core concept:
The vast majority of existing tokenizers require only a single term space:
In the future, some analyzers may need multiple term spaces. For example, the same text may simultaneously produce word terms, subword terms, phonetic terms, stemmed terms, or analyzer-specific auxiliary terms. When these terms require independent doc length, avgdl, or df, they should go into different term spaces.
This document focuses on lexical full-text search. Cross-language semantic matching should continue to be handled by vector search or hybrid search.
Motivation
The current FTS model is:
This model works well for single-tokenizer text. V3 takes this model as its default path.
V3 adds a narrower format capability: when an analyzer produces multiple term sets with different statistical semantics, the index format can express that “a single field produces terms through multiple analysis channels, and maintains independent BM25 statistics for those terms.”
Multiple term spaces are a general format capability, applicable to any language and any analyzer strategy.
For example, a future analyzer might produce:
If all these terms are mixed into a single BM25 space:
The design goal of FTS V3 is to allow these term spaces to be separated statistically when needed, while keeping the single-term-space path close to V2 in cost and behavior.
User-Visible Behavior
Default FTS behavior continues to align with current semantics:
This still means the existing default tokenizer and filters.
Existing tokenizer options continue to work:
In V3, these tokenizers remain single-space indexes:
In the future, new analyzers can be explicitly enabled, for example:
Whether multiple term spaces are produced is determined by the actual output of the analyzer; language, locale, or domain hints can participate in this decision as analyzer options.
Term Spaces
First-principles definition:
When two groups of terms require independent handling of the following statistics or semantics, use different term spaces:
V3 must support single-space:
Future versions may support multi-space:
These names are interpretive metadata. The format layer relies on stable
term_space_id.Example:
A Unicode baseline analyzer could produce only single-space terms:
A more complex analyzer in the future could produce two spaces:
The same mechanism can also be used for other languages and strategies, such as compound splitting, morphology, phonetic search, or stemming/exact dual-space. Term spaces express the differences in statistical semantics between different term sets.
Parameters
V3 continues to use the existing
InvertedIndexParamsas the user-facing API for creating indexes.Tokenizer/analyzer behavior is fixed at index creation; users switch tokenizers, filters, or analyzer behavior by dropping and recreating the index. V3 continues to encode this information using existing metadata mechanisms.
V3 should continue to store
InvertedIndexParamsin the existingparamsmetadata. This already covers the information needed for query-time analyzer construction, such as:V3 continues to use the existing configuration abstraction. The first version adds term-space layout metadata necessary for multi-space.
Suggested minimal additional metadata:
Explanation:
term_space_id = 0.term_spaces, and the array index is theterm_space_id.term_spacesare for debug/display; query execution uses the array index.The physical encoding of
term_spacesuses the existing Lance index metadata mechanism.On-Disk Format
V3 continues to use the existing file layout:
The format supports multiple term spaces; single-space V3 maintains the V2 fast path.
metadata.lance
metadata.lancestores index-level metadata via schema metadata and deleted fragments via row data.The FTS format version continues to be expressed using the existing index version mechanism.
Required schema metadata:
Logical example of
term_spaces:Here
primaryandsubwordare display names. Format semantics are determined by array index:Row data:
Manifest details may retain a summary for planning; query execution reads persisted params and optional
term_spacesfrommetadata.lance. Switching tokenizer/analyzer behavior is accomplished by dropping and recreating the index.part__tokens.lance
The token dictionary is responsible for mapping
(term_space_id, term)to a token id. V3 has two physical shapes.Single-space V3:
It can use the same logical schema as the V2 FST token set:
This way, single-space V3 is close to V2 in storage and query cost.
Multi-space V3:
FST keys use a reserved binary term-space prefix:
Example:
Token ids within a partition are globally unique. This is the format definition for V3 multi-space.
Therefore,
invert.lancecan continue to look up posting lists by token id only. The query analysis stage knows which term space a term belongs to and finds the corresponding token id via the space-aware key.part__invert.lance
Posting lists continue to be indexed by token id:
Logical schema:
Posting payloads continue to store:
In V3,
_max_scoreand per-block max scores are computed using the actual scoring model, ensuring that WAND pruning uses the correct score upper bound.Because token ids are globally unique,
invert.lancecontinues to index posting rows by token id only.part__docs.lance
Document statistics are the key to V3 multi-term-spaces.
Single-space V3 can keep a V2-compatible schema:
At runtime this is interpreted as:
Multi-space V3 uses extensible per-space lengths:
Example:
These fields allow different term spaces to use independent BM25 statistics:
Independent doc length allows the statistics for auxiliary terms such as subword, phonetic, and stemmed terms to be maintained separately from primary terms.
Query and Scoring Semantics
V3 query flow:
Single-space scoring is equivalent to existing BM25:
Multi-space scoring:
The first version of scoring uses an unweighted sum of per-space BM25.
Requirements:
PostingIteratormust know the term space for each token;For rows outside indexed fragments that must take the flat path, the flat path uses the same analyzer and the same term-space-aware scoring model, so that scores from indexed and unindexed results remain comparable.
Compatibility
V1/V2 indices remain readable.
For the same tokenizer and filters, V3 single-space should match V2 behavior. This is the first compatibility gate.
Append / update:
Optimize / compaction:
Default user behavior remains compatible with V2. In the future, V3 may become the default write format for new FTS indexes; the default analyzer will continue to be determined by existing tokenizer defaults.
Comparison with Industry Practices
Lucene’s
Analyzerconverts text into index terms and is a field-aware analysis strategy; Lucene also provides analyzer packages for ICU, Japanese, Chinese, phonetic, and others. This shows that analysis behavior is a core semantic that search systems need to record and reproduce. Lucene BM25 statistics such as average field length and idf are also computed per field.Elasticsearch and OpenSearch multi-fields both allow “re-indexing the same field with different analyzers into different subfields.” This aligns with the motivation for term spaces: the same original text can have multiple analyzed representations. Elasticsearch/OpenSearch implement this through multiple Lucene fields; Lance V3 expresses the same capability within a single FTS index via term spaces.
Elasticsearch’s
combined_fieldsuses a BM25F-like approach to score multiple text fields as a combined field, and the documentation notes that it requires participating fields to have the same search analyzer and that the clause count grows with fields × terms. The takeaway for Lance is that multiple term spaces need to control query fan-out, and scoring requires an explicit statistical model.Typesense’s locale-specific search supports per-field locale and provides
pre_segmented_queryto ensure alignment between indexing and query tokenization. This supports two conclusions: first, analyzer consistency needs to be persisted; second, complex language or domain tokenizers require explicit tokenizer controls.Meilisearch uses a multilingual tokenizer pipeline, and in its multilingual dataset guide recommends splitting indexes by language first; if a single index is used, it suggests using localized attributes/query locales to align document and query tokenization, and warns that performance and relevancy may degrade as languages mix and grow. This supports the direction of Lance V3: keep the V2 single-statistical-space behavior by default, and enable multi-space storage when the analyzer explicitly requires it.
Tantivy’s
TextAnalyzer/ token filter model is close to Lance’s current tokenizer design, indicating that a single token stream remains the default primary path. V3 continues this primary path and enables multi-space when the analyzer explicitly needs multiple statistical spaces.References to official documentation:
Beta Was this translation helpful? Give feedback.
All reactions