{"version":3,"file":"cassandra.cjs","names":["VectorStore","args: CassandraLibArgs","value: T | T[]","primaryKeyArg: Column[]","nonKeyColumnsArg: Column[]","defaultColumn: Column","columns: Column | Column[]","columnName: string","embeddings: EmbeddingsInterface","CassandraTable","vectors: number[][]","documents: Document[]","query: number[]","k: number","filter?: WhereClause","includeEmbedding?: boolean","orderBy: Filter","Document","query: string","options: MaxMarginalRelevanceSearchOptions<this[\"FilterType\"]>","texts: string[]","metadatas: object | object[]","docs: Document[]"],"sources":["../../src/vectorstores/cassandra.ts"],"sourcesContent":["import { v4 as uuidv4 } from \"uuid\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport {\n  VectorStore,\n  MaxMarginalRelevanceSearchOptions,\n} from \"@langchain/core/vectorstores\";\nimport { Document } from \"@langchain/core/documents\";\nimport { maximalMarginalRelevance } from \"@langchain/core/utils/math\";\n\nimport {\n  CassandraClientArgs,\n  Column,\n  Filter,\n  WhereClause,\n  CassandraTableArgs,\n  CassandraTable,\n} from \"../utils/cassandra.js\";\n\nexport type SupportedVectorTypes = \"cosine\" | \"dot_product\" | \"euclidean\";\n\nexport interface CassandraLibArgs\n  extends CassandraClientArgs,\n    Omit<CassandraTableArgs, \"nonKeyColumns\" | \"keyspace\"> {\n  // keyspace is optional on CassandraClientArgs, but mandatory on CassandraTableArgs; we make it mandatory here\n  keyspace: string;\n  vectorType?: SupportedVectorTypes;\n  dimensions: number;\n  metadataColumns?: Column[];\n  nonKeyColumns?: Column | Column[];\n}\n\n/**\n * Class for interacting with the Cassandra database. It extends the\n * VectorStore class and provides methods for adding vectors and\n * documents, searching for similar vectors, and creating instances from\n * texts or documents.\n */\nexport class CassandraStore extends VectorStore {\n  declare FilterType: WhereClause;\n\n  private readonly table: CassandraTable;\n\n  private readonly idColumnAutoName = \"id\";\n\n  private readonly idColumnAutoGenerated: boolean;\n\n  private readonly vectorColumnName = \"vector\";\n\n  private readonly vectorColumn: Column;\n\n  private readonly textColumnName = \"text\";\n\n  private readonly textColumn: Column;\n\n  private readonly metadataColumnDefaultName = \"metadata\";\n\n  private readonly metadataColumns: Column[];\n\n  private readonly similarityColumn: Column;\n\n  private readonly embeddingColumnAlias = \"embedding\";\n\n  _vectorstoreType(): string {\n    return \"cassandra\";\n  }\n\n  private _cleanArgs(\n    args: CassandraLibArgs\n  ): CassandraLibArgs & { metadataColumns: Column[]; nonKeyColumns: Column[] } {\n    const {\n      table,\n      dimensions,\n      primaryKey,\n      nonKeyColumns,\n      indices,\n      metadataColumns,\n      vectorType = \"cosine\",\n    } = args;\n\n    if (!table || !dimensions) {\n      throw new Error(\"Missing required arguments\");\n    }\n\n    // Utility function to ensure the argument is treated as an array\n    function _toArray<T>(value: T | T[]): T[] {\n      return Array.isArray(value) ? value : [value];\n    }\n\n    const indicesArg = indices || [];\n\n    // Use the primary key if provided, else default to a single auto-generated UUID column\n    let primaryKeyArg: Column[];\n    if (primaryKey) {\n      primaryKeyArg = _toArray(primaryKey);\n    } else {\n      primaryKeyArg = [\n        { name: this.idColumnAutoName, type: \"uuid\", partition: true },\n      ];\n    }\n\n    // The combined nonKeyColumns and metadataColumns, de-duped by name\n    const combinedColumns = [\n      ..._toArray(nonKeyColumns || []),\n      ..._toArray(metadataColumns || []),\n    ];\n\n    const deduplicatedColumns = combinedColumns.filter(\n      (col, index, self) => self.findIndex((c) => c.name === col.name) === index\n    );\n\n    const nonKeyColumnsArg: Column[] = [...deduplicatedColumns];\n\n    // If no metadata columns are specified, add a default metadata column consistent with Langchain Python\n    if (nonKeyColumnsArg.length === 0) {\n      nonKeyColumnsArg.push({\n        name: this.metadataColumnDefaultName,\n        type: \"map<text, text>\",\n      });\n      indicesArg.push({\n        name: `idx_${this.metadataColumnDefaultName}_${table}_keys`,\n        value: `(keys(${this.metadataColumnDefaultName}))`,\n      });\n      indicesArg.push({\n        name: `idx_${this.metadataColumnDefaultName}_${table}_entries`,\n        value: `(entries(${this.metadataColumnDefaultName}))`,\n      });\n    }\n\n    const addDefaultNonKeyColumnIfNeeded = (defaultColumn: Column) => {\n      const column = nonKeyColumnsArg.find(\n        (col) => col.name === defaultColumn.name\n      );\n      if (!column) {\n        nonKeyColumnsArg.push(defaultColumn);\n      }\n    };\n\n    addDefaultNonKeyColumnIfNeeded({ name: this.textColumnName, type: \"text\" });\n    addDefaultNonKeyColumnIfNeeded({\n      name: this.vectorColumnName,\n      type: `VECTOR<FLOAT,${dimensions}>`,\n      alias: this.embeddingColumnAlias,\n    });\n\n    // If no index is specified for the vector column, add a default index\n    if (\n      !indicesArg.some((index) =>\n        new RegExp(`\\\\(\\\\s*${this.vectorColumnName.toLowerCase()}\\\\s*\\\\)`).test(\n          index.value.toLowerCase()\n        )\n      )\n    ) {\n      indicesArg.push({\n        name: `idx_${this.vectorColumnName}_${table}`,\n        value: `(${this.vectorColumnName})`,\n        options: `{'similarity_function': '${vectorType.toLowerCase()}'}`,\n      });\n    }\n\n    // Metadata the user will see excludes vector column and text column\n    const metadataColumnsArg = [...primaryKeyArg, ...nonKeyColumnsArg].filter(\n      (column) =>\n        column.name !== this.vectorColumnName &&\n        column.name !== this.textColumnName\n    );\n\n    return {\n      ...args,\n      vectorType,\n      primaryKey: primaryKeyArg,\n      nonKeyColumns: nonKeyColumnsArg,\n      metadataColumns: metadataColumnsArg,\n      indices: indicesArg,\n    };\n  }\n\n  private _getColumnByName(\n    columns: Column | Column[],\n    columnName: string\n  ): Column {\n    const columnsArray = Array.isArray(columns) ? columns : [columns];\n    const column = columnsArray.find((col) => col.name === columnName);\n    if (!column) {\n      throw new Error(`Column ${columnName} not found`);\n    }\n    return column;\n  }\n\n  constructor(embeddings: EmbeddingsInterface, args: CassandraLibArgs) {\n    super(embeddings, args);\n\n    const cleanedArgs = this._cleanArgs(args);\n\n    // This check here to help the compiler understand that nonKeyColumns will always\n    // have values after the _cleanArgs call. It is the cleanest way to handle the fact\n    // that the compiler is not able to make this determination, no matter how hard we try!\n    if (!cleanedArgs.nonKeyColumns || cleanedArgs.nonKeyColumns.length === 0) {\n      throw new Error(\"No non-key columns provided\");\n    }\n\n    this.vectorColumn = this._getColumnByName(\n      cleanedArgs.nonKeyColumns,\n      this.vectorColumnName\n    );\n    this.textColumn = this._getColumnByName(\n      cleanedArgs.nonKeyColumns,\n      this.textColumnName\n    );\n\n    this.similarityColumn = {\n      name: `similarity_${cleanedArgs.vectorType}(${this.vectorColumnName},?)`,\n      alias: \"similarity_score\",\n      type: \"\",\n    };\n    this.idColumnAutoGenerated = !args.primaryKey;\n    this.metadataColumns = cleanedArgs.metadataColumns;\n\n    this.table = new CassandraTable(cleanedArgs);\n  }\n\n  /**\n   * Method to save vectors to the Cassandra database.\n   * @param vectors Vectors to save.\n   * @param documents The documents associated with the vectors.\n   * @returns Promise that resolves when the vectors have been added.\n   */\n  async addVectors(vectors: number[][], documents: Document[]): Promise<void> {\n    if (vectors.length === 0) {\n      return;\n    }\n    // Prepare the values for upsert\n    const values = vectors.map((vector, index) => {\n      const document = documents[index];\n      const docMetadata = document.metadata || {};\n\n      // If idColumnAutoGenerated is true and ID is not provided, generate a UUID\n      if (\n        this.idColumnAutoGenerated &&\n        (docMetadata[this.idColumnAutoName] === undefined ||\n          docMetadata[this.idColumnAutoName] === \"\")\n      ) {\n        docMetadata[this.idColumnAutoName] = uuidv4();\n      }\n\n      // Construct the row\n      const row = [];\n\n      // Add values for each metadata column\n      this.metadataColumns.forEach((col) => {\n        row.push(docMetadata[col.name] || null);\n      });\n\n      // Add the text content and vector\n      row.push(document.pageContent);\n      row.push(new Float32Array(vector));\n\n      return row;\n    });\n\n    const columns = [\n      ...this.metadataColumns,\n      { name: this.textColumnName, type: \"\" },\n      { name: this.vectorColumnName, type: \"\" },\n    ];\n\n    return this.table.upsert(values, columns);\n  }\n\n  getCassandraTable(): CassandraTable {\n    return this.table;\n  }\n\n  /**\n   * Method to add documents to the Cassandra database.\n   * @param documents The documents to add.\n   * @returns Promise that resolves when the documents have been added.\n   */\n  async addDocuments(documents: Document[]): Promise<void> {\n    return this.addVectors(\n      await this.embeddings.embedDocuments(documents.map((d) => d.pageContent)),\n      documents\n    );\n  }\n\n  /**\n   * Helper method to search for vectors that are similar to a given query vector.\n   * @param query The query vector.\n   * @param k The number of similar Documents to return.\n   * @param filter Optional filter to be applied as a WHERE clause.\n   * @param includeEmbedding Whether to include the embedding vectors in the results.\n   * @returns Promise that resolves with an array of tuples, each containing a Document and a score.\n   */\n  async search(\n    query: number[],\n    k: number,\n    filter?: WhereClause,\n    includeEmbedding?: boolean\n  ): Promise<[Document, number][]> {\n    const vectorAsFloat32Array = new Float32Array(query);\n\n    const similarityColumnWithBinds = {\n      ...this.similarityColumn,\n      binds: [vectorAsFloat32Array],\n    };\n\n    const queryCols = [\n      ...this.metadataColumns,\n      this.textColumn,\n      similarityColumnWithBinds,\n    ];\n\n    if (includeEmbedding) {\n      queryCols.push(this.vectorColumn);\n    }\n\n    const orderBy: Filter = {\n      name: this.vectorColumnName,\n      operator: \"ANN OF\",\n      value: [vectorAsFloat32Array],\n    };\n\n    const queryResultSet = await this.table.select(\n      queryCols,\n      filter,\n      [orderBy],\n      k\n    );\n\n    return queryResultSet?.rows.map((row) => {\n      const textContent = row[this.textColumnName];\n      const sanitizedRow = { ...row };\n      delete sanitizedRow[this.textColumnName];\n      delete sanitizedRow.similarity_score;\n\n      Object.keys(sanitizedRow).forEach((key) => {\n        if (sanitizedRow[key] === null) {\n          delete sanitizedRow[key];\n        }\n      });\n\n      return [\n        new Document({ pageContent: textContent, metadata: sanitizedRow }),\n        row.similarity_score,\n      ];\n    });\n  }\n\n  /**\n   * Method to search for vectors that are similar to a given query vector.\n   * @param query The query vector.\n   * @param k The number of similar Documents to return.\n   * @param filter Optional filter to be applied as a WHERE clause.\n   * @returns Promise that resolves with an array of tuples, each containing a Document and a score.\n   */\n  async similaritySearchVectorWithScore(\n    query: number[],\n    k: number,\n    filter?: WhereClause\n  ): Promise<[Document, number][]> {\n    return this.search(query, k, filter, false);\n  }\n\n  /**\n   * Method to search for vectors that are similar to a given query vector, but with\n   * the results selected using the maximal marginal relevance.\n   * @param query The query string.\n   * @param options.k The number of similar Documents to return.\n   * @param options.fetchK=4*k The number of records to fetch before passing to the MMR algorithm.\n   * @param options.lambda=0.5 The degree of diversity among the results between 0 (maximum diversity) and 1 (minimum diversity).\n   * @param options.filter Optional filter to be applied as a WHERE clause.\n   * @returns List of documents selected by maximal marginal relevance.\n   */\n  async maxMarginalRelevanceSearch(\n    query: string,\n    options: MaxMarginalRelevanceSearchOptions<this[\"FilterType\"]>\n  ): Promise<Document[]> {\n    const { k, fetchK = 4 * k, lambda = 0.5, filter } = options;\n\n    const queryEmbedding = await this.embeddings.embedQuery(query);\n\n    const queryResults = await this.search(\n      queryEmbedding,\n      fetchK,\n      filter,\n      true\n    );\n\n    const embeddingList = queryResults.map(\n      (doc) => doc[0].metadata[this.embeddingColumnAlias]\n    );\n\n    const mmrIndexes = maximalMarginalRelevance(\n      queryEmbedding,\n      embeddingList,\n      lambda,\n      k\n    );\n\n    return mmrIndexes.map((idx) => {\n      const doc = queryResults[idx][0];\n      delete doc.metadata[this.embeddingColumnAlias];\n      return doc;\n    });\n  }\n\n  /**\n   * Static method to create an instance of CassandraStore from texts.\n   * @param texts The texts to use.\n   * @param metadatas The metadata associated with the texts.\n   * @param embeddings The embeddings to use.\n   * @param args The arguments for the CassandraStore.\n   * @returns Promise that resolves with a new instance of CassandraStore.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: object | object[],\n    embeddings: EmbeddingsInterface,\n    args: CassandraLibArgs\n  ): Promise<CassandraStore> {\n    const docs: Document[] = [];\n\n    for (let index = 0; index < texts.length; index += 1) {\n      const metadata = Array.isArray(metadatas) ? metadatas[index] : metadatas;\n      const doc = new Document({\n        pageContent: texts[index],\n        metadata,\n      });\n      docs.push(doc);\n    }\n\n    return CassandraStore.fromDocuments(docs, embeddings, args);\n  }\n\n  /**\n   * Static method to create an instance of CassandraStore from documents.\n   * @param docs The documents to use.\n   * @param embeddings The embeddings to use.\n   * @param args The arguments for the CassandraStore.\n   * @returns Promise that resolves with a new instance of CassandraStore.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    args: CassandraLibArgs\n  ): Promise<CassandraStore> {\n    const instance = new this(embeddings, args);\n    await instance.addDocuments(docs);\n    return instance;\n  }\n\n  /**\n   * Static method to create an instance of CassandraStore from an existing\n   * index.\n   * @param embeddings The embeddings to use.\n   * @param args The arguments for the CassandraStore.\n   * @returns Promise that resolves with a new instance of CassandraStore.\n   */\n  static async fromExistingIndex(\n    embeddings: EmbeddingsInterface,\n    args: CassandraLibArgs\n  ): Promise<CassandraStore> {\n    const instance = new this(embeddings, args);\n    return instance;\n  }\n}\n"],"mappings":"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"}