Context Search and Standard Search for Term Proximity in FlexSearch: Key Differences Explained
Standard search in FlexSearch intersects posting lists without regard to term order or distance, while context search enforces term proximity using a sliding window controlled by the depth parameter, preserving order and supporting bidirectional matching.
The nextapps-de/flexsearch library provides two fundamentally different modes for querying indexed documents. Understanding how context search and standard search handle term proximity is critical for building accurate full-text search features, as the choice between modes determines whether the engine respects word order and distance constraints.
What Is Standard Search in FlexSearch?
Standard search is the default behavior in FlexSearch. When you execute a query containing multiple terms, the engine simply intersects the posting lists of each individual term.
In src/index/search.js, this path avoids the keyword variable entirely. The engine collects document IDs for each term and returns the intersection, meaning:
- Term order is ignored – "quick brown" matches "brown quick"
- No distance limit – terms may appear arbitrarily far apart in the document
- Any tokenizer works –
strict,default,full, and custom tokenizers are all compatible
What Is Context Search in FlexSearch?
Context search activates when you configure a depth value greater than zero or pass { context: true } to a specific query. This mode implements a sliding window algorithm that enforces proximity constraints.
According to the implementation in src/index/search.js (lines 81-86), the engine determines context mode with:
context = this.depth && context !== false;
let query_terms = this.encoder.encode(query, !context);
Key characteristics include:
- Order preservation – Terms must appear in the query order (or reverse order when bidirectional)
- Proximity enforcement – The
depthparameter defines a moving window over the token stream; matches must stay within this window - Strict tokenizer requirement – Only the
stricttokenizer is supported because exact token positions are required (see the warning insrc/index.jslines 102-106)
Key Differences Between Context and Standard Search
Term Order and Directionality
Standard search treats the query as an unordered set. Context search treats it as a sequence. When context.bidirectional is enabled (the default), the sliding window accepts matches in forward or reverse order, allowing "eight six four" to match against a document containing "four five six seven eight".
Proximity Constraints
The depth option controls how far apart terms can be. With depth: 1, terms must be adjacent. With depth: 2, one intervening token is allowed. Standard search has no equivalent limit.
Tokenizer Compatibility
As enforced in src/index.js, context search requires the strict tokenizer. Using default or full tokenizers triggers a console warning and disables context functionality. Standard search works with any tokenizer configuration.
Performance Characteristics
Standard search is generally faster for large term sets because it can sort posting lists by frequency and intersect efficiently. Context search incurs overhead from maintaining the sliding window and keyword references, particularly when depth values are high or bidirectional scanning is active.
Configuration and Implementation Details
Enabling Context Search in src/index.js
The constructor processes context settings at lines 94-99:
this.depth = (tmp === "strict" && context.depth) || 0;
this.bidirectional = context.bidirectional !== false;
If tokenize is not "strict" and context.depth is set, the engine warns developers at lines 102-106 that the strict tokenizer is required for context search to function correctly.
The Sliding Window Algorithm in src/index/search.js
The core logic resides in the search routine. When context is active, the algorithm:
- Treats the first token as the keyword
- Iterates subsequent terms while maintaining a reference to the current keyword
- Uses
_get_arrayto check if the next term falls within the depth window relative to the keyword - Slides the window forward when matches succeed or collapses it when they fail
The implementation comment at lines 165-172 explains this as a "moving window" that slides over the token stream. If the window collapses (terms too far apart), the match fails unless suggestion mode triggers a fallback to standard search (lines 175-183).
Practical Code Examples
Standard Search Behavior
import FlexSearch from "flexsearch";
const idxStd = new FlexSearch.Index({
tokenize: "strict"
});
idxStd.add(1, "zero one two three four five six seven eight nine ten");
// Order ignored: matches regardless of word order
console.log(idxStd.search("three zero")); // [1]
// Distance ignored: matches regardless of gap size
console.log(idxStd.search("three ten")); // [1]
Context Search with Depth Constraint
const idxCtx = new FlexSearch.Index({
tokenize: "strict",
context: { depth: 2 }
});
idxCtx.add(1, "zero one two three four five six seven eight nine ten");
// Adjacent terms match
console.log(idxCtx.search("zero one")); // [1]
// Terms within depth window (one token between)
console.log(idxCtx.search("zero two")); // [1]
// Terms outside depth window fail
console.log(idxCtx.search("zero three")); // [] (gap of two tokens exceeds depth:2)
Bidirectional Matching
// Default bidirectional mode (context.bidirectional defaults to true)
console.log(idxCtx.search("eight six four")); // [1] (matches reverse order)
// Disable bidirectional
const idxNoBi = new FlexSearch.Index({
tokenize: "strict",
context: { depth: 2, bidirectional: false }
});
idxNoBi.add(1, "zero one two three four five six seven eight nine ten");
console.log(idxNoBi.search("eight six four")); // [] (reverse order rejected)
Disabling Context Per-Query
// Temporarily use standard search on a context-enabled index
console.log(idxCtx.search("zero three", { context: false })); // [1]
Summary
- Standard search intersects posting lists without regard to term order or distance, working with any tokenizer but providing no proximity control.
- Context search activates with
depth > 0and enforces term proximity using a sliding window algorithm that requires thestricttokenizer. - Order sensitivity distinguishes the modes: standard ignores sequence while context preserves it (optionally bidirectional).
- Performance differs slightly due to context search's window maintenance and keyword tracking overhead.
- Configuration occurs at initialization via the
contextoption or per-query via thecontextboolean flag.
Frequently Asked Questions
Can I use context search with any tokenizer?
No. Context search requires the strict tokenizer because the sliding window algorithm depends on exact token positions. If you configure context: { depth: N } with a non-strict tokenizer like default or full, FlexSearch emits a warning in src/index.js (lines 102-106) and disables context functionality.
What happens if search terms are outside the depth window?
When terms exceed the configured depth distance, the sliding window collapses and the match fails. For example, with depth: 2, searching for "zero three" against the text "zero one two three" returns no results because two tokens ("one", "two") separate the search terms, exceeding the window size. If suggestion mode is enabled, FlexSearch falls back to standard search behavior (lines 175-183 in src/index/search.js).
Is context search slower than standard search?
Context search incurs a slight performance penalty compared to standard search. Standard search can sort posting lists by frequency and intersect them efficiently in any order. Context search must maintain a reference to the current keyword and slide the proximity window across the token stream, which adds overhead—particularly with high depth values or when bidirectional scanning is enabled.
Can I disable bidirectional matching?
Yes. By default, context.bidirectional is true, allowing matches in reverse order (e.g., "eight six four" matching "four five six seven eight"). To enforce strict forward-only order, initialize the index with context: { depth: N, bidirectional: false }. This configuration is processed in src/index.js (line 99) and enforced during the sliding window iteration in src/index/search.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →