forked from langchain-ai/langchainjs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Added filtering ability to supabase (langchain-ai#905)
* Added filtering ability to supabase * Supabase metadata filter polish: small fix, adds integration test, update docs * Skip Supabase integration test reliant on outside setup * Use FakeEmbeddings in unit test * Update docs --------- Co-authored-by: Jacob Lee <[email protected]>
- Loading branch information
Showing
6 changed files
with
154 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
examples/src/indexes/vector_stores/supabase_with_metadata_filter.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import { SupabaseVectorStore } from "langchain/vectorstores/supabase"; | ||
import { OpenAIEmbeddings } from "langchain/embeddings/openai"; | ||
import { createClient } from "@supabase/supabase-js"; | ||
|
||
// First, follow set-up instructions at | ||
// https://js.langchain.com/docs/modules/indexes/vector_stores/integrations/supabase | ||
|
||
const privateKey = process.env.SUPABASE_PRIVATE_KEY; | ||
if (!privateKey) throw new Error(`Expected env var SUPABASE_PRIVATE_KEY`); | ||
|
||
const url = process.env.SUPABASE_URL; | ||
if (!url) throw new Error(`Expected env var SUPABASE_URL`); | ||
|
||
export const run = async () => { | ||
const client = createClient(url, privateKey); | ||
|
||
const vectorStore = await SupabaseVectorStore.fromTexts( | ||
["Hello world", "Hello world", "Hello world"], | ||
[{ user_id: 2 }, { user_id: 1 }, { user_id: 3 }], | ||
new OpenAIEmbeddings(), | ||
{ | ||
client, | ||
tableName: "documents", | ||
queryName: "match_documents", | ||
} | ||
); | ||
|
||
const result = await vectorStore.similaritySearch("Hello world", 1, { | ||
user_id: 3, | ||
}); | ||
|
||
console.log(result); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import { test, expect, jest } from "@jest/globals"; | ||
import { SupabaseClient } from "@supabase/supabase-js"; | ||
|
||
import { SupabaseVectorStore } from "../supabase.js"; | ||
|
||
import { FakeEmbeddings } from "../../embeddings/fake.js"; | ||
|
||
test("similaritySearchVectorWithScore should call RPC with the vectorstore filters", async () => { | ||
const supabaseClientMock = { | ||
rpc: jest.fn().mockReturnValue(Promise.resolve({ data: [] })), | ||
} as Partial<SupabaseClient>; | ||
|
||
const embeddings = new FakeEmbeddings(); | ||
const vectorStore = new SupabaseVectorStore(embeddings, { | ||
client: supabaseClientMock as SupabaseClient, | ||
tableName: "documents", | ||
queryName: "match_documents", | ||
filter: { a: 2 }, | ||
}); | ||
await vectorStore.similaritySearchVectorWithScore([1, 2, 3], 5); | ||
expect(supabaseClientMock.rpc).toHaveBeenCalledWith("match_documents", { | ||
filter: { a: 2 }, | ||
query_embedding: [1, 2, 3], | ||
match_count: 5, | ||
}); | ||
}); | ||
|
||
test("similaritySearchVectorWithScore should call RPC with the passed filters", async () => { | ||
const supabaseClientMock = { | ||
rpc: jest.fn().mockReturnValue(Promise.resolve({ data: [] })), | ||
} as Partial<SupabaseClient>; | ||
|
||
const embeddings = new FakeEmbeddings(); | ||
const vectorStore = new SupabaseVectorStore(embeddings, { | ||
client: supabaseClientMock as SupabaseClient, | ||
tableName: "documents", | ||
queryName: "match_documents", | ||
}); | ||
|
||
await vectorStore.similaritySearchVectorWithScore([1, 2, 3], 5, { b: 3 }); | ||
expect(supabaseClientMock.rpc).toHaveBeenCalledWith("match_documents", { | ||
filter: { b: 3 }, | ||
query_embedding: [1, 2, 3], | ||
match_count: 5, | ||
}); | ||
}); |