UNPKG

@langchain/community

Version:
1 lines • 10.9 kB
{"version":3,"file":"usearch.cjs","names":["SaveableVectorStore","embeddings: EmbeddingsInterface","args: USearchArgs","documents: Document[]","index: Index","vectors: number[][]","Index","MetricKind","ScalarKind","query: number[]","k: number","return_list: [Document, number][]","uuid","directory: string","texts: string[]","metadatas: object[] | object","dbConfig?: {\n docstore?: SynchronousInMemoryDocstore;\n }","docs: Document[]","Document"],"sources":["../../src/vectorstores/usearch.ts"],"sourcesContent":["import { Index, MetricKind, ScalarKind } from \"usearch\";\nimport * as uuid from \"uuid\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { SaveableVectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\nimport { SynchronousInMemoryDocstore } from \"../stores/doc/in_memory.js\";\n\n/**\n * Interface that defines the arguments that can be passed to the\n * `USearch` constructor. It includes optional properties for a\n * `docstore`, `index`, and `mapping`.\n */\nexport interface USearchArgs {\n docstore?: SynchronousInMemoryDocstore;\n index?: Index;\n mapping?: Record<number, string>;\n}\n\n/**\n * Class that extends `SaveableVectorStore` and provides methods for\n * adding documents and vectors to a `usearch` index, performing\n * similarity searches, and saving the index.\n */\nexport class USearch extends SaveableVectorStore {\n _index?: Index;\n\n _mapping: Record<number, string>;\n\n docstore: SynchronousInMemoryDocstore;\n\n args: USearchArgs;\n\n _vectorstoreType(): string {\n return \"usearch\";\n }\n\n constructor(embeddings: EmbeddingsInterface, args: USearchArgs) {\n super(embeddings, args);\n this.args = args;\n this._index = args.index;\n this._mapping = args.mapping ?? {};\n this.embeddings = embeddings;\n this.docstore = args?.docstore ?? new SynchronousInMemoryDocstore();\n }\n\n /**\n * Method that adds documents to the `usearch` index. It generates\n * embeddings for the documents and adds them to the index.\n * @param documents An array of `Document` instances to be added to the index.\n * @returns A promise that resolves with an array of document IDs.\n */\n async addDocuments(documents: Document[]) {\n const texts = documents.map(({ pageContent }) => pageContent);\n return this.addVectors(\n await this.embeddings.embedDocuments(texts),\n documents\n );\n }\n\n public get index(): Index {\n if (!this._index) {\n throw new Error(\n \"Vector store not initialised yet. Try calling `fromTexts` or `fromDocuments` first.\"\n );\n }\n return this._index;\n }\n\n private set index(index: Index) {\n this._index = index;\n }\n\n /**\n * Method that adds vectors to the `usearch` index. It also updates the\n * mapping between vector IDs and document IDs.\n * @param vectors An array of vectors to be added to the index.\n * @param documents An array of `Document` instances corresponding to the vectors.\n * @returns A promise that resolves with an array of document IDs.\n */\n async addVectors(vectors: number[][], documents: Document[]) {\n if (vectors.length === 0) {\n return [];\n }\n if (vectors.length !== documents.length) {\n throw new Error(`Vectors and documents must have the same length`);\n }\n const dv = vectors[0].length;\n if (!this._index) {\n this._index = new Index(dv, MetricKind.L2sq, ScalarKind.F32, 16);\n }\n const d = this.index.dimensions();\n if (dv !== d) {\n throw new Error(\n `Vectors must have the same length as the number of dimensions (${d})`\n );\n }\n\n const docstoreSize = this.index.size();\n const documentIds = [];\n for (let i = 0; i < vectors.length; i += 1) {\n const documentId = uuid.v4();\n documentIds.push(documentId);\n const id = Number(docstoreSize) + i;\n this.index.add(BigInt(id), new Float32Array(vectors[i]));\n this._mapping[id] = documentId;\n this.docstore.add({ [documentId]: documents[i] });\n }\n return documentIds;\n }\n\n /**\n * Method that performs a similarity search in the `usearch` index. It\n * returns the `k` most similar documents to a given query vector, along\n * with their similarity scores.\n * @param query The query vector.\n * @param k The number of most similar documents to return.\n * @returns A promise that resolves with an array of tuples, each containing a `Document` and its similarity score.\n */\n async similaritySearchVectorWithScore(query: number[], k: number) {\n const d = this.index.dimensions();\n if (query.length !== d) {\n throw new Error(\n `Query vector must have the same length as the number of dimensions (${d})`\n );\n }\n if (k > this.index.size()) {\n const total = this.index.size();\n console.warn(\n `k (${k}) is greater than the number of elements in the index (${total}), setting k to ${total}`\n );\n // eslint-disable-next-line no-param-reassign\n k = Number(total);\n }\n const result = this.index.search(new Float32Array(query), k);\n\n const return_list: [Document, number][] = [];\n for (\n let i = 0;\n i < result.keys.length && i < result.distances.length;\n i += 1\n ) {\n const uuid = this._mapping[Number(result.keys[i])];\n return_list.push([this.docstore.search(uuid), result.distances[i]]);\n }\n\n return return_list;\n }\n\n /**\n * Method that saves the `usearch` index and the document store to disk.\n * @param directory The directory where the index and document store should be saved.\n * @returns A promise that resolves when the save operation is complete.\n */\n async save(directory: string) {\n const fs = await import(\"node:fs/promises\");\n const path = await import(\"node:path\");\n await fs.mkdir(directory, { recursive: true });\n await Promise.all([\n this.index.save(path.join(directory, \"usearch.index\")),\n await fs.writeFile(\n path.join(directory, \"docstore.json\"),\n JSON.stringify([\n Array.from(this.docstore._docs.entries()),\n this._mapping,\n ])\n ),\n ]);\n }\n\n /**\n * Static method that creates a new `USearch` instance from a list of\n * texts. It generates embeddings for the texts and adds them to the\n * `usearch` index.\n * @param texts An array of texts to be added to the index.\n * @param metadatas Metadata associated with the texts.\n * @param embeddings An instance of `Embeddings` used to generate embeddings for the texts.\n * @param dbConfig Optional configuration for the document store.\n * @returns A promise that resolves with a new `USearch` instance.\n */\n static async fromTexts(\n texts: string[],\n metadatas: object[] | object,\n embeddings: EmbeddingsInterface,\n dbConfig?: {\n docstore?: SynchronousInMemoryDocstore;\n }\n ): Promise<USearch> {\n const docs: Document[] = [];\n for (let i = 0; i < texts.length; i += 1) {\n const metadata = Array.isArray(metadatas) ? metadatas[i] : metadatas;\n const newDoc = new Document({\n pageContent: texts[i],\n metadata,\n });\n docs.push(newDoc);\n }\n return this.fromDocuments(docs, embeddings, dbConfig);\n }\n\n /**\n * Static method that creates a new `USearch` instance from a list of\n * documents. It generates embeddings for the documents and adds them to\n * the `usearch` index.\n * @param docs An array of `Document` instances to be added to the index.\n * @param embeddings An instance of `Embeddings` used to generate embeddings for the documents.\n * @param dbConfig Optional configuration for the document store.\n * @returns A promise that resolves with a new `USearch` instance.\n */\n static async fromDocuments(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig?: {\n docstore?: SynchronousInMemoryDocstore;\n }\n ): Promise<USearch> {\n const args: USearchArgs = {\n docstore: dbConfig?.docstore,\n };\n const instance = new this(embeddings, args);\n await instance.addDocuments(docs);\n return instance;\n }\n}\n"],"mappings":"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"}