From 238028767a4ccdd4eb1928e868ec4ac9c3a6e9d2 Mon Sep 17 00:00:00 2001 From: Gatefixer <313497061+lancedb-gatefixer[bot]@users.noreply.github.com> Date: Wed, 5 Aug 2026 22:27:18 +0000 Subject: [PATCH] docs(node): clarify full-text search filtering --- docs/src/js/classes/Query.md | 32 ++++++++++++++++++--------- docs/src/js/classes/VectorQuery.md | 35 +++++++++++++++++++++--------- nodejs/examples/filtering.test.ts | 17 +++++++++++++++ nodejs/lancedb/query.ts | 29 ++++++++++++++++++++----- 4 files changed, 88 insertions(+), 25 deletions(-) diff --git a/docs/src/js/classes/Query.md b/docs/src/js/classes/Query.md index 6ebaebd75..aa0702974 100644 --- a/docs/src/js/classes/Query.md +++ b/docs/src/js/classes/Query.md @@ -541,7 +541,17 @@ where(predicate): this A filter statement to be applied to this query. -The filter should be supplied as an SQL query string. For example: +Filters are applied before full-text and vector searches by default; no +separate prefilter call is needed. For vector searches only, use +[VectorQuery#postfilter](VectorQuery.md#postfilter) to apply the filter after the search. + +The filter should be supplied as an SQL query string. + +Filtering performance can often be improved by creating a scalar index +on the filter column(s). + +Calling this multiple times combines the filters with a logical AND rather +than replacing the previous filter. #### Parameters @@ -551,18 +561,20 @@ The filter should be supplied as an SQL query string. For example: `this` -#### Example +#### Examples ```ts -x > 10 -y > 0 AND y < 100 -x > 5 OR y = 'test' +const results = await table + .search("puppy", "fts") + .where("meta = 'foo'") + .limit(10) + .toArray(); +``` -Filtering performance can often be improved by creating a scalar index -on the filter column(s). - -Calling this multiple times combines the filters with a logical AND rather -than replacing the previous filter. +```ts +query.where("x > 10"); +query.where("y > 0 AND y < 100"); +query.where("x > 5 OR y = 'test'"); ``` #### Inherited from diff --git a/docs/src/js/classes/VectorQuery.md b/docs/src/js/classes/VectorQuery.md index f9412c76d..9c864b454 100644 --- a/docs/src/js/classes/VectorQuery.md +++ b/docs/src/js/classes/VectorQuery.md @@ -560,6 +560,9 @@ postfilter(): VectorQuery If this is called then filtering will happen after the vector search instead of before. +This method is only available for vector search queries. Full-text search +filters are always applied before the search. + By default filtering will be performed before the vector search. This is how filtering is typically understood to work. This prefilter step does add some additional latency. Creating a scalar index on the filter column(s) can @@ -790,7 +793,17 @@ where(predicate): this A filter statement to be applied to this query. -The filter should be supplied as an SQL query string. For example: +Filters are applied before full-text and vector searches by default; no +separate prefilter call is needed. For vector searches only, use +[VectorQuery#postfilter](VectorQuery.md#postfilter) to apply the filter after the search. + +The filter should be supplied as an SQL query string. + +Filtering performance can often be improved by creating a scalar index +on the filter column(s). + +Calling this multiple times combines the filters with a logical AND rather +than replacing the previous filter. #### Parameters @@ -800,18 +813,20 @@ The filter should be supplied as an SQL query string. For example: `this` -#### Example +#### Examples ```ts -x > 10 -y > 0 AND y < 100 -x > 5 OR y = 'test' +const results = await table + .search("puppy", "fts") + .where("meta = 'foo'") + .limit(10) + .toArray(); +``` -Filtering performance can often be improved by creating a scalar index -on the filter column(s). - -Calling this multiple times combines the filters with a logical AND rather -than replacing the previous filter. +```ts +query.where("x > 10"); +query.where("y > 0 AND y < 100"); +query.where("x > 5 OR y = 'test'"); ``` #### Inherited from diff --git a/nodejs/examples/filtering.test.ts b/nodejs/examples/filtering.test.ts index ab77a5851..0f0c24ba0 100644 --- a/nodejs/examples/filtering.test.ts +++ b/nodejs/examples/filtering.test.ts @@ -47,5 +47,22 @@ test("filtering examples", async () => { .limit(5) .toArray(); // --8<-- [end:orderby_search] + + const ftsTable = await db.createTable("myFts", [ + { text: "Frodo was a happy puppy", category: "pet" }, + { text: "A puppy training guide", category: "guide" }, + { text: "There are several kittens playing", category: "pet" }, + ]); + await ftsTable.createIndex("text", { config: lancedb.Index.fts() }); + + // --8<-- [start:fts_prefilter] + const ftsResults = await ftsTable + .search("puppy", "fts") + .where("category = 'pet'") + .limit(10) + .toArray(); + // --8<-- [end:fts_prefilter] + expect(ftsResults).toHaveLength(1); + expect(ftsResults[0].category).toBe("pet"); }); }); diff --git a/nodejs/lancedb/query.ts b/nodejs/lancedb/query.ts index 843a1276f..501bbcda6 100644 --- a/nodejs/lancedb/query.ts +++ b/nodejs/lancedb/query.ts @@ -363,17 +363,33 @@ export class StandardQueryBase< /** * A filter statement to be applied to this query. * - * The filter should be supplied as an SQL query string. For example: - * @example - * x > 10 - * y > 0 AND y < 100 - * x > 5 OR y = 'test' + * Filters are applied before full-text and vector searches by default; no + * separate prefilter call is needed. For vector searches only, use + * {@link VectorQuery#postfilter} to apply the filter after the search. + * + * The filter should be supplied as an SQL query string. * * Filtering performance can often be improved by creating a scalar index * on the filter column(s). * * Calling this multiple times combines the filters with a logical AND rather * than replacing the previous filter. + * + * @example Filter a full-text search + * ```ts + * const results = await table + * .search("puppy", "fts") + * .where("meta = 'foo'") + * .limit(10) + * .toArray(); + * ``` + * + * @example SQL filter expressions + * ```ts + * query.where("x > 10"); + * query.where("y > 0 AND y < 100"); + * query.where("x > 5 OR y = 'test'"); + * ``` */ where(predicate: string): this { this.doCall((inner: NativeQueryType) => inner.onlyIf(predicate)); @@ -669,6 +685,9 @@ export class VectorQuery extends StandardQueryBase { * If this is called then filtering will happen after the vector search instead of * before. * + * This method is only available for vector search queries. Full-text search + * filters are always applied before the search. + * * By default filtering will be performed before the vector search. This is how * filtering is typically understood to work. This prefilter step does add some * additional latency. Creating a scalar index on the filter column(s) can