@langchain/community
Version:
Third-party integrations for LangChain.js
1 lines • 17.5 kB
Source Map (JSON)
{"version":3,"file":"neon.cjs","names":["VectorStore","embeddings: EmbeddingsInterface","config: NeonPostgresArgs","rows: (string | Record<string, any>)[][]","useIdColumn: boolean","vectors: number[][]","documents: Document[]","options?: { ids?: string[] }","query: number[]","k: number","filter?: this[\"FilterType\"]","_filter: this[\"FilterType\"]","Document","params: { ids?: string[]; deleteAll?: boolean }","texts: string[]","metadatas: object[] | object","dbConfig: NeonPostgresArgs","docs: Document[]"],"sources":["../../src/vectorstores/neon.ts"],"sourcesContent":["import { neon } from \"@neondatabase/serverless\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\n\ntype Metadata = Record<string, string | number | Record<\"in\", string[]>>;\n\n/**\n * Interface that defines the arguments required to create a\n * `NeonPostgres` instance. It includes Postgres connection options,\n * table name, filter, and verbosity level.\n */\nexport interface NeonPostgresArgs {\n connectionString: string;\n tableName?: string;\n schemaName?: string;\n columns?: {\n idColumnName?: string;\n vectorColumnName?: string;\n contentColumnName?: string;\n metadataColumnName?: string;\n };\n filter?: Metadata;\n verbose?: boolean;\n}\n\n/**\n * Class that provides an interface to a Neon Postgres database. It\n * extends the `VectorStore` base class and implements methods for adding\n * documents and vectors, performing similarity searches, and ensuring the\n * existence of a table in the database.\n */\nexport class NeonPostgres extends VectorStore {\n declare FilterType: Metadata;\n\n tableName: string;\n\n schemaName?: string;\n\n idColumnName: string;\n\n vectorColumnName: string;\n\n contentColumnName: string;\n\n metadataColumnName: string;\n\n filter?: Metadata;\n\n _verbose?: boolean;\n\n neonConnectionString: string;\n\n _vectorstoreType(): string {\n return \"neon-postgres\";\n }\n\n constructor(embeddings: EmbeddingsInterface, config: NeonPostgresArgs) {\n super(embeddings, config);\n this._verbose =\n config.verbose ?? getEnvironmentVariable(\"LANGCHAIN_VERBOSE\") === \"true\";\n\n this.neonConnectionString = config.connectionString;\n this.tableName = config.tableName ?? \"vectorstore_documents\";\n this.schemaName = config.schemaName;\n this.filter = config.filter;\n\n this.vectorColumnName = config.columns?.vectorColumnName ?? \"embedding\";\n this.contentColumnName = config.columns?.contentColumnName ?? \"text\";\n this.idColumnName = config.columns?.idColumnName ?? \"id\";\n this.metadataColumnName = config.columns?.metadataColumnName ?? \"metadata\";\n }\n\n get computedTableName() {\n return typeof this.schemaName !== \"string\"\n ? `${this.tableName}`\n : `\"${this.schemaName}\".\"${this.tableName}\"`;\n }\n\n /**\n * Static method to create a new `NeonPostgres` instance from a\n * connection. It creates a table if one does not exist.\n *\n * @param embeddings - Embeddings instance.\n * @param fields - `NeonPostgresArgs` instance.\n * @returns A new instance of `NeonPostgres`.\n */\n static async initialize(\n embeddings: EmbeddingsInterface,\n config: NeonPostgresArgs\n ): Promise<NeonPostgres> {\n const neonVectorStore = new NeonPostgres(embeddings, config);\n await neonVectorStore.ensureTableInDatabase();\n return neonVectorStore;\n }\n\n /**\n * Constructs the SQL query for inserting rows into the specified table.\n *\n * @param rows - The rows of data to be inserted, consisting of values and records.\n * @param chunkIndex - The starting index for generating query placeholders based on chunk positioning.\n * @returns The complete SQL INSERT INTO query string.\n */\n protected async runInsertQuery(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n rows: (string | Record<string, any>)[][],\n useIdColumn: boolean\n ) {\n const placeholders = rows.map((row, index) => {\n const base = index * row.length;\n return `(${row.map((_, j) => `$${base + 1 + j}`)})`;\n });\n const queryString = `\n INSERT INTO ${this.computedTableName} (\n ${useIdColumn ? `${this.idColumnName},` : \"\"}\n ${this.contentColumnName}, \n ${this.vectorColumnName}, \n ${this.metadataColumnName}\n ) VALUES ${placeholders.join(\", \")}\n ON CONFLICT (${this.idColumnName}) \n DO UPDATE \n SET \n ${this.contentColumnName} = EXCLUDED.${this.contentColumnName},\n ${this.vectorColumnName} = EXCLUDED.${this.vectorColumnName},\n ${this.metadataColumnName} = EXCLUDED.${this.metadataColumnName}\n RETURNING ${this.idColumnName}\n `;\n\n const flatValues = rows.flat();\n const sql = neon(this.neonConnectionString);\n return await sql(queryString, flatValues);\n }\n\n /**\n * Method to add vectors to the vector store. It converts the vectors into\n * rows and inserts them into the database.\n *\n * @param vectors - Array of vectors.\n * @param documents - Array of `Document` instances.\n * @param options - Optional arguments for adding documents\n * @returns Promise that resolves when the vectors have been added.\n */\n async addVectors(\n vectors: number[][],\n documents: Document[],\n options?: { ids?: string[] }\n ): Promise<string[]> {\n if (options?.ids !== undefined && options?.ids.length !== vectors.length) {\n throw new Error(\n `If provided, the length of \"ids\" must be the same as the number of vectors.`\n );\n }\n\n const rows = vectors.map((embedding, idx) => {\n const embeddingString = `[${embedding.join(\",\")}]`;\n const row = [\n documents[idx].pageContent,\n embeddingString,\n documents[idx].metadata,\n ];\n if (options?.ids) {\n return [options.ids[idx], ...row];\n }\n return row;\n });\n\n const chunkSize = 500;\n const ids = [];\n for (let i = 0; i < rows.length; i += chunkSize) {\n const chunk = rows.slice(i, i + chunkSize);\n try {\n const result = await this.runInsertQuery(\n chunk,\n options?.ids !== undefined\n );\n ids.push(...result.map((row) => row[this.idColumnName]));\n } catch (e) {\n console.error(e);\n throw new Error(`Error inserting: ${(e as Error).message}`);\n }\n }\n return ids;\n }\n\n /**\n * Method to perform a similarity search in the vector store. It returns\n * the `k` most similar documents to the query vector, along with their\n * similarity scores.\n *\n * @param query - Query vector.\n * @param k - Number of most similar documents to return.\n * @param filter - Optional filter to apply to the search.\n * @returns Promise that resolves with an array of tuples, each containing a `Document` and its similarity score.\n */\n async similaritySearchVectorWithScore(\n query: number[],\n k: number,\n filter?: this[\"FilterType\"]\n ): Promise<[Document, number][]> {\n const embeddingString = `[${query.join(\",\")}]`;\n const _filter: this[\"FilterType\"] = filter ?? {};\n\n const whereClauses = [];\n const parameters = [embeddingString, k];\n let paramCount = parameters.length;\n\n // The vector to query with, and the num of results are the first\n // two parameters. The rest of the parameters are the filter values\n for (const [key, value] of Object.entries(_filter)) {\n if (typeof value === \"object\" && value !== null) {\n const currentParamCount = paramCount;\n const placeholders = value.in\n .map((_, index) => `$${currentParamCount + index + 1}`)\n .join(\",\");\n whereClauses.push(\n `${this.metadataColumnName}->>'${key}' IN (${placeholders})`\n );\n parameters.push(...value.in);\n paramCount += value.in.length;\n } else {\n paramCount += 1;\n whereClauses.push(\n `${this.metadataColumnName}->>'${key}' = $${paramCount}`\n );\n parameters.push(value);\n }\n }\n\n const whereClause = whereClauses.length\n ? `WHERE ${whereClauses.join(\" AND \")}`\n : \"\";\n const queryString = `\n SELECT *, ${this.vectorColumnName} <=> $1 as \"_distance\"\n FROM ${this.computedTableName}\n ${whereClause}\n ORDER BY \"_distance\" ASC\n LIMIT $2;`;\n\n const sql = neon(this.neonConnectionString);\n const documents = await sql(queryString, parameters);\n\n const results = [] as [Document, number][];\n for (const doc of documents) {\n if (doc._distance != null && doc[this.contentColumnName] != null) {\n const document = new Document({\n pageContent: doc[this.contentColumnName],\n metadata: doc[this.metadataColumnName],\n });\n results.push([document, doc._distance]);\n }\n }\n return results;\n }\n\n /**\n * Method to add documents to the vector store. It converts the documents into\n * vectors, and adds them to the store.\n *\n * @param documents - Array of `Document` instances.\n * @param options - Optional arguments for adding documents\n * @returns Promise that resolves when the documents have been added.\n */\n async addDocuments(\n documents: Document[],\n options?: { ids?: string[] }\n ): Promise<string[]> {\n const texts = documents.map(({ pageContent }) => pageContent);\n return this.addVectors(\n await this.embeddings.embedDocuments(texts),\n documents,\n options\n );\n }\n\n /**\n * Method to delete documents from the vector store. It deletes the\n * documents that match the provided ids.\n *\n * @param ids - Array of document ids.\n * @param deleteAll - Boolean to delete all documents.\n * @returns Promise that resolves when the documents have been deleted.\n */\n async delete(params: { ids?: string[]; deleteAll?: boolean }): Promise<void> {\n const sql = neon(this.neonConnectionString);\n\n if (params.ids !== undefined) {\n await sql(\n `DELETE FROM ${this.computedTableName} \n WHERE ${this.idColumnName} \n IN (${params.ids.map((_, idx) => `$${idx + 1}`)})`,\n params.ids\n );\n } else if (params.deleteAll) {\n await sql(`TRUNCATE TABLE ${this.tableName}`);\n }\n }\n\n /**\n * Method to ensure the existence of the table to store vectors in\n * the database. It creates the table if it does not already exist.\n *\n * @returns Promise that resolves when the table has been ensured.\n */\n async ensureTableInDatabase(): Promise<void> {\n const sql = neon(this.neonConnectionString);\n\n await sql(`CREATE EXTENSION IF NOT EXISTS vector;`);\n await sql(`CREATE EXTENSION IF NOT EXISTS \"uuid-ossp\";`);\n\n await sql(`\n CREATE TABLE IF NOT EXISTS ${this.computedTableName} (\n ${this.idColumnName} uuid NOT NULL DEFAULT uuid_generate_v4() PRIMARY KEY,\n ${this.contentColumnName} text,\n ${this.metadataColumnName} jsonb,\n ${this.vectorColumnName} vector\n );\n `);\n }\n\n /**\n * Static method to create a new `NeonPostgres` instance from an\n * array of texts and their metadata. It converts the texts into\n * `Document` instances and adds them to the store.\n *\n * @param texts - Array of texts.\n * @param metadatas - Array of metadata objects or a single metadata object.\n * @param embeddings - Embeddings instance.\n * @param dbConfig - `NeonPostgresArgs` instance.\n * @returns Promise that resolves with a new instance of `NeonPostgresArgs`.\n */\n static async fromTexts(\n texts: string[],\n metadatas: object[] | object,\n embeddings: EmbeddingsInterface,\n dbConfig: NeonPostgresArgs\n ): Promise<NeonPostgres> {\n const docs = [];\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 to create a new `NeonPostgres` instance from an\n * array of `Document` instances. It adds the documents to the store.\n *\n * @param docs - Array of `Document` instances.\n * @param embeddings - Embeddings instance.\n * @param dbConfig - `NeonPostgreseArgs` instance.\n * @returns Promise that resolves with a new instance of `NeonPostgres`.\n */\n static async fromDocuments(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig: NeonPostgresArgs\n ): Promise<NeonPostgres> {\n const instance = await this.initialize(embeddings, dbConfig);\n await instance.addDocuments(docs);\n return instance;\n }\n}\n"],"mappings":"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"}