Filtering
Pre and post-filtering
LanceDB supports filtering of query results based on metadata fields. By default, post-filtering is performed on the top-k results returned by the vector search. However, pre-filtering is also an option that performs the filter prior to vector search. This can be useful to narrow down on the search space on a very large dataset to reduce query latency.
Note that both pre-filtering and post-filtering can yield false positives. For pre-filtering, if the filter is too selective, it might eliminate relevant items that the vector search would have otherwise identified as a good match. In this case, increasing nprobes
parameter will help reduce such false positives. It is recommended to set use_index=false
if you know that the filter is highly selective.
Similarly, a highly selective post-filter can lead to false positives. Increasing both nprobes
and refine_factor
can mitigate this issue. When deciding between pre-filtering and post-filtering, pre-filtering is generally the safer choice if you're uncertain.
Note
Creating a scalar index accelerates filtering
SQL filters
Because it's built on top of DataFusion, LanceDB embraces the utilization of standard SQL expressions as predicates for filtering operations. It can be used during vector search, update, and deletion operations.
Currently, Lance supports a growing list of SQL expressions.
>
,>=
,<
,<=
,=
AND
,OR
,NOT
IS NULL
,IS NOT NULL
IS TRUE
,IS NOT TRUE
,IS FALSE
,IS NOT FALSE
IN
LIKE
,NOT LIKE
CAST
regexp_match(column, pattern)
- DataFusion Functions
For example, the following filter string is acceptable:
If your column name contains special 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.
Field names containing periods (.
) are not supported.
Literals for dates, timestamps, and decimals can be written by writing the string value after the type name. For example
For timestamp columns, the precision can be specified as a number in the type parameter. Microsecond precision (6) is the default.
SQL | Time unit |
---|---|
timestamp(0) |
Seconds |
timestamp(3) |
Milliseconds |
timestamp(6) |
Microseconds |
timestamp(9) |
Nanoseconds |
LanceDB internally stores data in Apache Arrow format. The mapping from SQL types to Arrow types is:
SQL type | Arrow type |
---|---|
boolean |
Boolean |
tinyint / tinyint unsigned |
Int8 / UInt8 |
smallint / smallint unsigned |
Int16 / UInt16 |
int or integer / int unsigned or integer unsigned |
Int32 / UInt32 |
bigint / bigint unsigned |
Int64 / UInt64 |
float |
Float32 |
double |
Float64 |
decimal(precision, scale) |
Decimal128 |
date |
Date32 |
timestamp |
Timestamp 1 |
string |
Utf8 |
binary |
Binary |
Filtering without Vector Search
You can also filter your data without search.
If your table is large, this could potentially return a very large amount of data. Please be sure to use a limit
clause unless you're sure you want to return the whole result set.
-
See precision mapping in previous table. ↩