diff --git a/docs/search/filtering.mdx b/docs/search/filtering.mdx index 6602430..350b302 100644 --- a/docs/search/filtering.mdx +++ b/docs/search/filtering.mdx @@ -14,6 +14,39 @@ with filtering capabilities even on datasets containing billions of records. On hybrid queries, the same `where(...)` filter is applied to both the vector and full-text halves of the query. The prefilter or postfilter choice controls whether that happens before each subquery scores candidates or after the subquery top-k is produced. +## Chaining `where` clauses + +In more recent LanceDB SDK versions (see the callout box below for the exact version numbers), you can call `where(...)` (Python and TypeScript) or `only_if(...)` (Rust) more than once on the same query builder. Each additional filter is combined with the previous one using logical `AND`, so `where("a > 0").where("b < 10")` is equivalent to `where("(a > 0) AND (b < 10)")`. + +For a fixed predicate, writing one `where(...)` clause with `AND` is just as valid and often clearer. Chaining is mainly useful when code composes filters incrementally, such as applying a shared base predicate in a helper and then adding a per-call predicate at the query site. + + +```python Python icon="python" +# Both filters apply: item is in the list AND price is above 15. +result = ( + table.search([100, 102]) + .where("item IN ('foo', 'bar', 'baz')") + .where("price > 15.0") + .limit(3) + .to_arrow() +) +``` + +```typescript TypeScript icon="square-js" +// Both filters apply: item is in the list AND price is above 15. +const result = await table + .search([100, 102]) + .where("item IN ('foo', 'bar', 'baz')") + .where("price > 15.0") + .limit(3) + .toArray(); +``` + + + +In Python SDK versions before `0.34.0` and Rust/TypeScript SDK versions before `0.31.0`, a second `where(...)` or `only_if(...)` call replaced the first filter, so only the last predicate was applied. If your code needs to run on those older versions, write a single predicate with `AND` instead of chaining calls. When upgrading to the latest SDKs, review any existing chained filters and drop earlier calls you no longer want to apply. + + ## Example: Metadata Filtering To illustrate filtering capabilities, let's try four data points with combinations of vectors and metadata: