Run a complete filtering example
Run a complete filtering example
These examples use three sample records and hand-written vectors, so no
embedding service is needed. Each program creates a temporary local table
and removes it when finished.The query vector is closest to the gardening record, but the filter excludes
that category. The results contain only the two animal records.
- Python: Install with
pip install lancedb, save asfiltered_search.py, then runpython filtered_search.py. - TypeScript: Install with
npm install @lancedb/lancedb, save asfiltered_search.mts, then runnode filtered_search.mtswith Node.js 22.18 or later. - Rust: Download and extract the complete Rust examples, then run
cargo run --locked --bin filter_searchfrom the extracted directory.
Prefiltering and postfiltering
- Prefiltering, the default, limits the rows eligible for retrieval before search chooses its candidates.
- Postfiltering removes nonmatching rows after candidates are selected.
It can return fewer than
limitrows, including zero, even when matching records exist elsewhere in the table.
Filtering examples by language
The following excerpts use a connecteddb handle. Create this sample table
before running the queries beneath it; each query uses the same four records.
Combine predicates
Repeated filter calls combine predicates with logicalAND. For example, where("a > 0").where("b < 10") is equivalent to where("(a > 0) AND (b < 10)").
Use a single expression for a fixed filter. Chain calls when your application
builds the filter incrementally.
Filtering Without Vector Search
You can always filter your data without search. This is useful when you need to query based on metadata:limit() explicitly to control how many matching records your application
receives.
Pre-Filtering with Vector Search
Post-Filtering with Vector Search
Write SQL predicates
Pass a SQL expression as the filter string. These expressions also select rows for SDK update and delete operations; they are not standalone SQL statements. LanceDB supports a growing list of SQL expressions:Simple SQL Filters
For example, the following filter string is acceptable:Advanced SQL Filters
If your column name contains special characters, upper-case characters, or is a SQL Keyword, you can use backtick (`) to escape it. For nested fields, each segment of the
path must be wrapped in backticks.
Periods separate nested fields. LanceDB does not allow a literal period in a
top-level column name; backticks do not remove that restriction.
Dates, Timestamps, Decimals
Literals for dates, timestamps, and decimals can be written by writing the string value after the type name. For example:Apache Arrow Mapping
LanceDB uses Arrow types for schemas and in-memory data. On disk, tables use the Lance format. The mapping from SQL types to Arrow types is:Speed up frequently used filters
Consider a scalar index on frequently filtered columns. Use the query plan to check whether a predicate uses that index. Functions or casts applied to a column can change which optimizations are available. For list columns, a label-list index supports membership filters such asarray_has_any and array_has_all.