-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
community[minor],docs[minor]: Add
UpstashVector
(#4288)
* add upstash vector integration * bump @upstash/vector * add docs * add chunk support, improve docs * address review * update vector sdk version * Apply suggestions from code review * update example * format * fix examples build * langchain[patch]: Make sitemap test integration (#4358) * rm from langchain proper --------- Co-authored-by: Brace Sproul <braceasproul@gmail.com>
- Loading branch information
1 parent
dcb8a18
commit 1f1bd36
Showing
12 changed files
with
532 additions
and
2 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import CodeBlock from "@theme/CodeBlock"; | ||
import CreateClientExample from "@examples/indexes/vector_stores/upstash/create_client.ts"; | ||
import IndexQueryExample from "@examples/indexes/vector_stores/upstash/index_and_query_docs.ts"; | ||
import DeleteExample from "@examples/indexes/vector_stores/upstash/delete_docs.ts"; | ||
import IntegrationInstallTooltip from "@mdx_components/integration_install_tooltip.mdx"; | ||
|
||
# Upstash Vector | ||
|
||
Upstash Vector is a REST based serverless vector database, designed for working with vector embeddings. | ||
|
||
## Setup | ||
|
||
1. Create Upstash Vector Index | ||
|
||
You can create an index from [Upstash Console](https://console.upstash.com/vector). For further reference, see [docs](https://upstash.com/docs/vector/overall/getstarted). | ||
|
||
2. Install Upstash Vector SDK. | ||
|
||
```bash npm2yarn | ||
npm install -S @upstash/vector | ||
``` | ||
|
||
We use OpenAI for the embeddings of the below examples. | ||
However, you can also create the embeddings using the model of your choice, that is available in the LangChain. | ||
|
||
<IntegrationInstallTooltip></IntegrationInstallTooltip> | ||
|
||
```bash npm2yarn | ||
npm install @langchain/openai @langchain/community | ||
``` | ||
|
||
## Create Upstash Vector Client | ||
|
||
There are two ways to create the client. You can either pass the credentials as string manually from the `.env` file (or as string variables), or you can retrieve the credentials from the environment automatically. | ||
|
||
<CodeBlock language="typescript">{CreateClientExample}</CodeBlock> | ||
|
||
## Index and Query Documents | ||
|
||
You can index the LangChain documents with any model of your choice, and perform a search over these documents. | ||
|
||
<CodeBlock language="typescript">{IndexQueryExample}</CodeBlock> | ||
|
||
## Delete Documents | ||
|
||
You can also delete the documents you've indexed previously. | ||
|
||
<CodeBlock language="typescript">{DeleteExample}</CodeBlock> |
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
22 changes: 22 additions & 0 deletions
22
examples/src/indexes/vector_stores/upstash/create_client.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,22 @@ | ||
import { Index } from "@upstash/vector"; | ||
import { OpenAIEmbeddings } from "@langchain/openai"; | ||
import { UpstashVectorStore } from "@langchain/community/vectorstores/upstash"; | ||
|
||
const embeddings = new OpenAIEmbeddings({}); | ||
|
||
// Creating the index with the provided credentials. | ||
const indexWithCredentials = new Index({ | ||
url: process.env.UPSTASH_VECTOR_REST_URL as string, | ||
token: process.env.UPSTASH_VECTOR_REST_TOKEN as string, | ||
}); | ||
|
||
const storeWithCredentials = new UpstashVectorStore(embeddings, { | ||
index: indexWithCredentials, | ||
}); | ||
|
||
// Creating the index from the environment variables automatically. | ||
const indexFromEnv = new Index(); | ||
|
||
const storeFromEnv = new UpstashVectorStore(embeddings, { | ||
index: indexFromEnv, | ||
}); |
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,28 @@ | ||
import { Index } from "@upstash/vector"; | ||
import { OpenAIEmbeddings } from "@langchain/openai"; | ||
import { UpstashVectorStore } from "@langchain/community/vectorstores/upstash"; | ||
|
||
const index = new Index({ | ||
url: process.env.UPSTASH_VECTOR_REST_URL as string, | ||
token: process.env.UPSTASH_VECTOR_REST_TOKEN as string, | ||
}); | ||
|
||
const embeddings = new OpenAIEmbeddings({}); | ||
|
||
const UpstashVector = new UpstashVectorStore(embeddings, { index }); | ||
|
||
// Creating the docs to be indexed. | ||
const createdAt = new Date().getTime(); | ||
|
||
const IDs = await UpstashVector.addDocuments([ | ||
{ pageContent: "hello", metadata: { a: createdAt + 1 } }, | ||
{ pageContent: "car", metadata: { a: createdAt } }, | ||
{ pageContent: "adjective", metadata: { a: createdAt } }, | ||
{ pageContent: "hi", metadata: { a: createdAt } }, | ||
]); | ||
|
||
// Waiting vectors to be indexed in the vector store. | ||
// eslint-disable-next-line no-promise-executor-return | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
||
await UpstashVector.delete({ ids: [IDs[0], IDs[2], IDs[3]] }); |
66 changes: 66 additions & 0 deletions
66
examples/src/indexes/vector_stores/upstash/index_and_query_docs.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,66 @@ | ||
import { Index } from "@upstash/vector"; | ||
import { OpenAIEmbeddings } from "@langchain/openai"; | ||
import { Document } from "@langchain/core/documents"; | ||
import { UpstashVectorStore } from "@langchain/community/vectorstores/upstash"; | ||
|
||
const index = new Index({ | ||
url: process.env.UPSTASH_VECTOR_REST_URL as string, | ||
token: process.env.UPSTASH_VECTOR_REST_TOKEN as string, | ||
}); | ||
|
||
const embeddings = new OpenAIEmbeddings({}); | ||
|
||
const UpstashVector = new UpstashVectorStore(embeddings, { index }); | ||
|
||
// Creating the docs to be indexed. | ||
const id = new Date().getTime(); | ||
const documents = [ | ||
new Document({ | ||
metadata: { name: id }, | ||
pageContent: "Hello there!", | ||
}), | ||
new Document({ | ||
metadata: { name: id }, | ||
pageContent: "What are you building?", | ||
}), | ||
new Document({ | ||
metadata: { time: id }, | ||
pageContent: "Upstash Vector is great for building AI applications.", | ||
}), | ||
new Document({ | ||
metadata: { time: id }, | ||
pageContent: "To be, or not to be, that is the question.", | ||
}), | ||
]; | ||
|
||
// Creating embeddings from the provided documents, and adding them to Upstash database. | ||
await UpstashVector.addDocuments(documents); | ||
|
||
// Waiting vectors to be indexed in the vector store. | ||
// eslint-disable-next-line no-promise-executor-return | ||
await new Promise((resolve) => setTimeout(resolve, 1000)); | ||
|
||
const queryResult = await UpstashVector.similaritySearchWithScore( | ||
"Vector database", | ||
2 | ||
); | ||
|
||
console.log(queryResult); | ||
/** | ||
[ | ||
[ | ||
Document { | ||
pageContent: 'Upstash Vector is great for building AI applications.', | ||
metadata: [Object] | ||
}, | ||
0.9016147 | ||
], | ||
[ | ||
Document { | ||
pageContent: 'What are you building?', | ||
metadata: [Object] | ||
}, | ||
0.8613077 | ||
] | ||
] | ||
*/ |
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
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
86 changes: 86 additions & 0 deletions
86
libs/langchain-community/src/vectorstores/tests/upstash.int.test.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,86 @@ | ||
/* eslint-disable no-process-env */ | ||
import { Index } from "@upstash/vector"; | ||
import { Document } from "@langchain/core/documents"; | ||
import { SyntheticEmbeddings } from "@langchain/core/utils/testing"; | ||
import { EmbeddingsInterface } from "@langchain/core/embeddings"; | ||
import { UpstashVectorStore } from "../upstash.js"; | ||
import { sleep } from "../../utils/time.js"; | ||
|
||
describe.skip("UpstashVectorStore", () => { | ||
let store: UpstashVectorStore; | ||
let embeddings: EmbeddingsInterface; | ||
let index: Index; | ||
|
||
beforeEach(async () => { | ||
index = new Index({ | ||
url: process.env.UPSTASH_VECTOR_REST_URL, | ||
token: process.env.UPSTASH_VECTOR_REST_TOKEN, | ||
}); | ||
|
||
embeddings = new SyntheticEmbeddings({ | ||
vectorSize: 1536, | ||
}); | ||
|
||
store = new UpstashVectorStore(embeddings, { | ||
index, | ||
}); | ||
|
||
expect(store).toBeDefined(); | ||
}); | ||
|
||
test("basic operations with documents", async () => { | ||
const createdAt = new Date().getTime(); | ||
|
||
const ids = await store.addDocuments([ | ||
{ pageContent: "hello", metadata: { a: createdAt + 1 } }, | ||
{ pageContent: "car", metadata: { a: createdAt } }, | ||
{ pageContent: "adjective", metadata: { a: createdAt } }, | ||
{ pageContent: "hi", metadata: { a: createdAt } }, | ||
]); | ||
|
||
// Sleeping for a second to make sure that all the indexing operations are finished. | ||
await sleep(1000); | ||
|
||
const results1 = await store.similaritySearchWithScore("hello!", 1); | ||
expect(results1).toHaveLength(1); | ||
|
||
expect([results1[0][0]]).toEqual([ | ||
new Document({ metadata: { a: createdAt + 1 }, pageContent: "hello" }), | ||
]); | ||
|
||
const results2 = await store.similaritySearchWithScore("testing!", 6); | ||
|
||
expect(results2).toHaveLength(4); | ||
|
||
await store.delete({ ids: ids.slice(2) }); | ||
|
||
const results3 = await store.similaritySearchWithScore("testing again!", 6); | ||
|
||
expect(results3).toHaveLength(2); | ||
}); | ||
|
||
test("UpstashVectorStore.fromText", async () => { | ||
const vectorStore = await UpstashVectorStore.fromTexts( | ||
["hello there!", "what are you building?", "vectors are great!"], | ||
[ | ||
{ id: 1, name: "text1" }, | ||
{ id: 2, name: "text2" }, | ||
{ id: 3, name: "text3" }, | ||
], | ||
embeddings, | ||
{ index } | ||
); | ||
|
||
// Sleeping for a second to make sure that all the indexing operations are finished. | ||
await sleep(1000); | ||
|
||
const results1 = await vectorStore.similaritySearch("vectors are great", 1); | ||
|
||
expect(results1).toEqual([ | ||
new Document({ | ||
pageContent: "vectors are great!", | ||
metadata: { id: 3, name: "text3" }, | ||
}), | ||
]); | ||
}); | ||
}); |
Oops, something went wrong.