{"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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"}