{"version":3,"file":"couchbase_search.cjs","names":["VectorStore","embedding: EmbeddingsInterface","config: CouchbaseSearchVectorStoreArgs","embeddings: EmbeddingsInterface","scopeCollectionMap: Record<string, any>","fields: any","metadataFields: { [key: string]: any }","queryEmbeddings: number[]","filter: CouchbaseSearchVectorStoreFilter","SearchRequest","VectorSearch","VectorQuery","docsWithScore: [Document, number][]","Document","query: string","documentsToInsert: {\n      [x: string]: any;\n    }[]","successfulDocIds: string[]","vectors: number[][]","documents: Document[]","options: AddVectorOptions","ids: string[] | undefined","metadata: any","id: string","index: number","docIds: string[]","texts: string[]","metadatas: any","ids: string[]"],"sources":["../../src/vectorstores/couchbase_search.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable import/no-extraneous-dependencies */\nimport { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport {\n  Bucket,\n  Cluster,\n  Collection,\n  Scope,\n  SearchRequest,\n  VectorQuery,\n  VectorSearch,\n} from \"couchbase\";\nimport { Document } from \"@langchain/core/documents\";\nimport { v4 as uuid } from \"uuid\";\n\n/**\n * This interface define the optional fields for adding vector\n * - `ids` - vector of ids for each document. If undefined, then uuid will be used\n * - `metadata` - vector of metadata object for each document\n */\nexport interface AddVectorOptions {\n  ids?: string[];\n  metadata?: Record<string, any>[];\n}\n\n/**\n * This interface defines the fields required to initialize a vector store\n * These are the fields part of config:\n * @property {Cluster} cluster - The Couchbase cluster that the store will interact with.\n * @property {string} bucketName - The name of the bucket in the Couchbase cluster.\n * @property {string} scopeName - The name of the scope within the bucket.\n * @property {string} collectionName - The name of the collection within the scope.\n * @property {string} indexName - The name of the index to be used for vector search.\n * @property {string} textKey - The key to be used for text in the documents. Defaults to \"text\".\n * @property {string} embeddingKey - The key to be used for embeddings in the documents. Defaults to \"embedding\".\n * @property {boolean} scopedIndex - Whether to use a scoped index for vector search. Defaults to true.\n * @property {AddVectorOptions} addVectorOptions - Options for adding vectors with specific id/metadata\n */\nexport interface CouchbaseSearchVectorStoreArgs {\n  cluster: Cluster;\n  bucketName: string;\n  scopeName: string;\n  collectionName: string;\n  indexName: string;\n  textKey?: string;\n  embeddingKey?: string;\n  scopedIndex?: boolean;\n  addVectorOptions?: AddVectorOptions;\n}\n\n/**\n * This type defines the search filters used in couchbase vector search\n * - `fields`: Optional list of fields to include in the\n * metadata of results. Note that these need to be stored in the index.\n * If nothing is specified, defaults to all the fields stored in the index.\n * - `searchOptions`:  Optional search options that are passed to Couchbase search. Defaults to empty object.\n */\ntype CouchbaseSearchVectorStoreFilter = {\n  fields?: any;\n  searchOptions?: any;\n};\n\n/**\n * Class for interacting with the Couchbase database. It extends the\n * VectorStore class and provides methods for adding vectors and\n * documents, and searching for similar vectors.\n * Initiate the class using initialize() method.\n */\nexport class CouchbaseSearchVectorStore extends VectorStore {\n  declare FilterType: CouchbaseSearchVectorStoreFilter;\n\n  private metadataKey = \"metadata\";\n\n  private readonly defaultTextKey = \"text\";\n\n  private readonly defaultScopedIndex = true;\n\n  private readonly defaultEmbeddingKey = \"embedding\";\n\n  private cluster: Cluster;\n\n  private _bucket: Bucket;\n\n  private _scope: Scope;\n\n  private _collection: Collection;\n\n  private bucketName: string;\n\n  private scopeName: string;\n\n  private collectionName: string;\n\n  private indexName: string;\n\n  private textKey = this.defaultTextKey;\n\n  private embeddingKey = this.defaultEmbeddingKey;\n\n  private scopedIndex: boolean;\n\n  /**\n   * The private constructor used to provide embedding to parent class.\n   * Initialize the class using static initialize() method\n   * @param embedding - object to generate embedding\n   * @param config -  the fields required to initialize a vector store\n   */\n  private constructor(\n    embedding: EmbeddingsInterface,\n    config: CouchbaseSearchVectorStoreArgs\n  ) {\n    super(embedding, config);\n  }\n\n  /**\n   * initialize class for interacting with the Couchbase database.\n   * It extends the VectorStore class and provides methods\n   * for adding vectors and documents, and searching for similar vectors.\n   * This also verifies the params\n   *\n   * @param embeddings - object to generate embedding\n   * @param config - the fields required to initialize a vector store\n   */\n  static async initialize(\n    embeddings: EmbeddingsInterface,\n    config: CouchbaseSearchVectorStoreArgs\n  ) {\n    const store = new CouchbaseSearchVectorStore(embeddings, config);\n\n    const {\n      cluster,\n      bucketName,\n      scopeName,\n      collectionName,\n      indexName,\n      textKey,\n      embeddingKey,\n      scopedIndex,\n    } = config;\n\n    store.cluster = cluster;\n    store.bucketName = bucketName;\n    store.scopeName = scopeName;\n    store.collectionName = collectionName;\n    store.indexName = indexName;\n    if (textKey) {\n      store.textKey = textKey;\n    } else {\n      store.textKey = store.defaultTextKey;\n    }\n\n    if (embeddingKey) {\n      store.embeddingKey = embeddingKey;\n    } else {\n      store.embeddingKey = store.defaultEmbeddingKey;\n    }\n\n    if (scopedIndex !== undefined) {\n      store.scopedIndex = scopedIndex;\n    } else {\n      store.scopedIndex = store.defaultScopedIndex;\n    }\n\n    try {\n      store._bucket = store.cluster.bucket(store.bucketName);\n      store._scope = store._bucket.scope(store.scopeName);\n      store._collection = store._scope.collection(store.collectionName);\n    } catch {\n      throw new Error(\n        \"Error connecting to couchbase, Please check connection and credentials\"\n      );\n    }\n\n    try {\n      if (\n        !(await store.checkBucketExists()) ||\n        !(await store.checkIndexExists()) ||\n        !(await store.checkScopeAndCollectionExists())\n      ) {\n        throw new Error(\"Error while initializing vector store\");\n      }\n    } catch (err) {\n      throw new Error(`Error while initializing vector store: ${err}`);\n    }\n    return store;\n  }\n\n  /**\n   * An asynchrononous method to verify the search indexes.\n   * It retrieves all indexes and checks if specified index is present.\n   *\n   * @throws - If the specified index does not exist in the database.\n   *\n   * @returns - returns promise true if no error is found\n   */\n  private async checkIndexExists(): Promise<boolean> {\n    if (this.scopedIndex) {\n      const allIndexes = await this._scope.searchIndexes().getAllIndexes();\n      const indexNames = allIndexes.map((index) => index.name);\n      if (!indexNames.includes(this.indexName)) {\n        throw new Error(\n          `Index ${this.indexName} does not exist. Please create the index before searching.`\n        );\n      }\n    } else {\n      const allIndexes = await this.cluster.searchIndexes().getAllIndexes();\n      const indexNames = allIndexes.map((index) => index.name);\n      if (!indexNames.includes(this.indexName)) {\n        throw new Error(\n          `Index ${this.indexName} does not exist. Please create the index before searching.`\n        );\n      }\n    }\n    return true;\n  }\n\n  /**\n   * An asynchronous method to verify the existence of a bucket.\n   * It retrieves the bucket using the bucket manager and checks if the specified bucket is present.\n   *\n   * @throws - If the specified bucket does not exist in the database.\n   *\n   * @returns - Returns a promise that resolves to true if no error is found, indicating the bucket exists.\n   */\n  private async checkBucketExists(): Promise<boolean> {\n    const bucketManager = this.cluster.buckets();\n    try {\n      await bucketManager.getBucket(this.bucketName);\n      return true;\n    } catch {\n      throw new Error(\n        `Bucket ${this.bucketName} does not exist. Please create the bucket before searching.`\n      );\n    }\n  }\n\n  /**\n   * An asynchronous method to verify the existence of a scope and a collection within that scope.\n   * It retrieves all scopes and collections in the bucket, and checks if the specified scope and collection are present.\n   *\n   * @throws - If the specified scope does not exist in the bucket, or if the specified collection does not exist in the scope.\n   *\n   * @returns - Returns a promise that resolves to true if no error is found, indicating the scope and collection exist.\n   */\n  private async checkScopeAndCollectionExists(): Promise<boolean> {\n    const scopeCollectionMap: Record<string, any> = {};\n\n    // Get a list of all scopes in the bucket\n    const scopes = await this._bucket.collections().getAllScopes();\n    for (const scope of scopes) {\n      scopeCollectionMap[scope.name] = [];\n\n      // Get a list of all the collections in the scope\n      for (const collection of scope.collections) {\n        scopeCollectionMap[scope.name].push(collection.name);\n      }\n    }\n\n    // Check if the scope exists\n    if (!Object.keys(scopeCollectionMap).includes(this.scopeName)) {\n      throw new Error(\n        `Scope ${this.scopeName} not found in Couchbase bucket ${this.bucketName}`\n      );\n    }\n\n    // Check if the collection exists in the scope\n    if (!scopeCollectionMap[this.scopeName].includes(this.collectionName)) {\n      throw new Error(\n        `Collection ${this.collectionName} not found in scope ${this.scopeName} in Couchbase bucket ${this.bucketName}`\n      );\n    }\n    return true;\n  }\n\n  _vectorstoreType(): string {\n    return \"couchbase-search\";\n  }\n\n  /**\n   * Formats couchbase metadata by removing `metadata.` from initials\n   * @param fields - all the fields of row\n   * @returns - formatted metadata fields\n   */\n  private formatMetadata = (fields: any) => {\n    const fieldsCopy = { ...fields };\n    delete fieldsCopy[this.textKey];\n    const metadataFields: { [key: string]: any } = {};\n    for (const key in fieldsCopy) {\n      if (Object.prototype.hasOwnProperty.call(fieldsCopy, key)) {\n        const newKey = key.replace(`${this.metadataKey}.`, \"\");\n        metadataFields[newKey] = fieldsCopy[key];\n      }\n    }\n    return metadataFields;\n  };\n\n  /**\n   * Performs a similarity search on the vectors in the Couchbase database and returns the documents and their corresponding scores.\n   *\n   * @param queryEmbeddings - Embedding vector to look up documents similar to.\n   * @param k - Number of documents to return. Defaults to 4.\n   * @param filter - Optional search filter that are passed to Couchbase search. Defaults to empty object.\n   * - `fields`: Optional list of fields to include in the\n   * metadata of results. Note that these need to be stored in the index.\n   * If nothing is specified, defaults to all the fields stored in the index.\n   * - `searchOptions`:  Optional search options that are passed to Couchbase search. Defaults to empty object.\n   *\n   * @returns - Promise of list of [document, score] that are the most similar to the query vector.\n   *\n   * @throws If the search operation fails.\n   */\n  async similaritySearchVectorWithScore(\n    queryEmbeddings: number[],\n    k = 4,\n    filter: CouchbaseSearchVectorStoreFilter = {}\n  ): Promise<[Document, number][]> {\n    let { fields } = filter;\n    const { searchOptions } = filter;\n\n    if (!fields) {\n      fields = [\"*\"];\n    }\n    if (\n      !(fields.length === 1 && fields[0] === \"*\") &&\n      !fields.includes(this.textKey)\n    ) {\n      fields.push(this.textKey);\n    }\n\n    const searchRequest = new SearchRequest(\n      VectorSearch.fromVectorQuery(\n        new VectorQuery(this.embeddingKey, queryEmbeddings).numCandidates(k)\n      )\n    );\n\n    let searchIterator;\n    const docsWithScore: [Document, number][] = [];\n    try {\n      if (this.scopedIndex) {\n        searchIterator = this._scope.search(this.indexName, searchRequest, {\n          limit: k,\n          fields,\n          raw: searchOptions,\n        });\n      } else {\n        searchIterator = this.cluster.search(this.indexName, searchRequest, {\n          limit: k,\n          fields,\n          raw: searchOptions,\n        });\n      }\n\n      const searchRows = (await searchIterator).rows;\n      for (const row of searchRows) {\n        const text = row.fields[this.textKey];\n        const metadataFields = this.formatMetadata(row.fields);\n        const searchScore = row.score;\n        const doc = new Document({\n          pageContent: text,\n          metadata: metadataFields,\n        });\n        docsWithScore.push([doc, searchScore]);\n      }\n    } catch (err) {\n      console.log(\"error received\");\n      throw new Error(`Search failed with error: ${err}`);\n    }\n    return docsWithScore;\n  }\n\n  /**\n   * Return documents that are most similar to the vector embedding.\n   *\n   * @param queryEmbeddings - Embedding to look up documents similar to.\n   * @param k - The number of similar documents to return. Defaults to 4.\n   * @param filter - Optional search filter that are passed to Couchbase search. Defaults to empty object.\n   * - `fields`: Optional list of fields to include in the\n   * metadata of results. Note that these need to be stored in the index.\n   * If nothing is specified, defaults to all the fields stored in the index.\n   * - `searchOptions`:  Optional search options that are passed to Couchbase search. Defaults to empty object.\n   *\n   * @returns - A promise that resolves to an array of documents that match the similarity search.\n   */\n  async similaritySearchByVector(\n    queryEmbeddings: number[],\n    k = 4,\n    filter: CouchbaseSearchVectorStoreFilter = {}\n  ): Promise<Document[]> {\n    const docsWithScore = await this.similaritySearchVectorWithScore(\n      queryEmbeddings,\n      k,\n      filter\n    );\n    const docs = [];\n    for (const doc of docsWithScore) {\n      docs.push(doc[0]);\n    }\n    return docs;\n  }\n\n  /**\n   * Return documents that are most similar to the query.\n   *\n   * @param query - Query to look up for similar documents\n   * @param k - The number of similar documents to return. Defaults to 4.\n   * @param filter - Optional search filter that are passed to Couchbase search. Defaults to empty object.\n   * - `fields`: Optional list of fields to include in the\n   * metadata of results. Note that these need to be stored in the index.\n   * If nothing is specified, defaults to all the fields stored in the index.\n   * - `searchOptions`:  Optional search options that are passed to Couchbase search. Defaults to empty object.\n   *\n   * @returns - Promise of list of documents that are most similar to the query.\n   */\n  async similaritySearch(\n    query: string,\n    k = 4,\n    filter: CouchbaseSearchVectorStoreFilter = {}\n  ): Promise<Document[]> {\n    const queryEmbeddings = await this.embeddings.embedQuery(query);\n    const docsWithScore = await this.similaritySearchVectorWithScore(\n      queryEmbeddings,\n      k,\n      filter\n    );\n    const docs = [];\n    for (const doc of docsWithScore) {\n      docs.push(doc[0]);\n    }\n    return docs;\n  }\n\n  /**\n   * Return documents that are most similar to the query with their scores.\n   *\n   * @param query - Query to look up for similar documents\n   * @param k - The number of similar documents to return. Defaults to 4.\n   * @param filter - Optional search filter that are passed to Couchbase search. Defaults to empty object.\n   * - `fields`: Optional list of fields to include in the\n   * metadata of results. Note that these need to be stored in the index.\n   * If nothing is specified, defaults to all the fields stored in the index.\n   * - `searchOptions`:  Optional search options that are passed to Couchbase search. Defaults to empty object.\n   *\n   * @returns - Promise of list of documents that are most similar to the query.\n   */\n  async similaritySearchWithScore(\n    query: string,\n    k = 4,\n    filter: CouchbaseSearchVectorStoreFilter = {}\n  ): Promise<[Document, number][]> {\n    const queryEmbeddings = await this.embeddings.embedQuery(query);\n    const docsWithScore = await this.similaritySearchVectorWithScore(\n      queryEmbeddings,\n      k,\n      filter\n    );\n    return docsWithScore;\n  }\n\n  /**\n   * upsert documents asynchronously into a couchbase collection\n   * @param documentsToInsert Documents to be inserted into couchbase collection with embeddings, original text and metadata\n   * @returns DocIds of the inserted documents\n   */\n  private async upsertDocuments(\n    documentsToInsert: {\n      [x: string]: any;\n    }[]\n  ) {\n    // Create promises for each document to be upserted\n    const upsertDocumentsPromises = documentsToInsert.map((document) => {\n      const currentDocumentKey = Object.keys(document)[0];\n      return this._collection\n        .upsert(currentDocumentKey, document[currentDocumentKey])\n        .then(() => currentDocumentKey)\n        .catch((e) => {\n          console.error(\"error received while upserting document\", e);\n          throw new Error(`Upsert failed with error: ${e}`);\n        });\n    });\n\n    try {\n      // Upsert all documents asynchronously\n      const docIds = await Promise.all(upsertDocumentsPromises);\n      const successfulDocIds: string[] = [];\n      for (const id of docIds) {\n        if (id) {\n          successfulDocIds.push(id);\n        }\n      }\n      return successfulDocIds;\n    } catch (e) {\n      console.error(\n        \"An error occurred with Promise.all at upserting all documents\",\n        e\n      );\n      throw e;\n    }\n  }\n\n  /**\n   * Add vectors and corresponding documents to a couchbase collection\n   * If the document IDs are passed, the existing documents (if any) will be\n   * overwritten with the new ones.\n   * @param vectors - The vectors to be added to the collection.\n   * @param documents - The corresponding documents to be added to the collection.\n   * @param options - Optional parameters for adding vectors.\n   * This may include the IDs and metadata of the documents to be added. Defaults to an empty object.\n   *\n   * @returns - A promise that resolves to an array of document IDs that were added to the collection.\n   */\n  public async addVectors(\n    vectors: number[][],\n    documents: Document[],\n    options: AddVectorOptions = {}\n  ): Promise<string[]> {\n    // Get document ids. if ids are not available then use UUIDs for each document\n    let ids: string[] | undefined = options ? options.ids : undefined;\n    if (ids === undefined) {\n      ids = Array.from({ length: documents.length }, () => uuid());\n    }\n\n    // Get metadata for each document. if metadata is not available, use empty object for each document\n    let metadata: any = options ? options.metadata : undefined;\n    if (metadata === undefined) {\n      metadata = Array.from({ length: documents.length }, () => ({}));\n    }\n\n    const documentsToInsert = ids.map((id: string, index: number) => ({\n      [id]: {\n        [this.textKey]: documents[index].pageContent,\n        [this.embeddingKey]: vectors[index],\n        [this.metadataKey]: metadata[index],\n      },\n    }));\n\n    let docIds: string[] = [];\n    try {\n      docIds = await this.upsertDocuments(documentsToInsert);\n    } catch (err) {\n      console.error(\"Error while adding vectors\", err);\n      throw err;\n    }\n\n    return docIds;\n  }\n\n  /**\n   * Run texts through the embeddings and persist in vectorstore.\n   * If the document IDs are passed, the existing documents (if any) will be\n   * overwritten with the new ones.\n   * @param documents - The corresponding documents to be added to the collection.\n   * @param options - Optional parameters for adding documents.\n   * This may include the IDs and metadata of the documents to be added. Defaults to an empty object.\n   *\n   * @returns - A promise that resolves to an array of document IDs that were added to the collection.\n   */\n  public async addDocuments(\n    documents: Document[],\n    options: AddVectorOptions = {}\n  ) {\n    const texts = documents.map(({ pageContent }) => pageContent);\n    const metadatas = documents.map((doc) => doc.metadata);\n    const optionsWithMetadata = {\n      ...options,\n      metadata: options.metadata ?? metadatas,\n    };\n    return this.addVectors(\n      await this.embeddings.embedDocuments(texts),\n      documents,\n      optionsWithMetadata\n    );\n  }\n\n  /**\n   * Create a new CouchbaseVectorStore from a set of documents.\n   * This function will initialize a new store, add the documents to it, and then return the store.\n   * @param documents - The documents to be added to the new store.\n   * @param embeddings - The embeddings to be used for the documents.\n   * @param config - The configuration for the new CouchbaseVectorStore. This includes the options for adding vectors.\n   *\n   * @returns - A promise that resolves to the new CouchbaseVectorStore that contains the added documents.\n   */\n  static async fromDocuments(\n    documents: Document[],\n    embeddings: EmbeddingsInterface,\n    config: CouchbaseSearchVectorStoreArgs\n  ): Promise<CouchbaseSearchVectorStore> {\n    const store = await this.initialize(embeddings, config);\n    await store.addDocuments(documents, config.addVectorOptions);\n    return store;\n  }\n\n  /**\n   * Create a new CouchbaseVectorStore from a set of texts.\n   * This function will convert each text and its corresponding metadata into a Document,\n   * initialize a new store, add the documents to it, and then return the store.\n   * @param texts - The texts to be converted into Documents and added to the new store.\n   * @param metadatas - The metadata for each text. If an array is passed, each text will have its corresponding metadata.\n   * If not, all texts will have the same metadata.\n   * @param embeddings - The embeddings to be used for the documents.\n   * @param config - The configuration for the new CouchbaseVectorStore. This includes the options for adding vectors.\n   *\n   * @returns - A promise that resolves to the new CouchbaseVectorStore that contains the added documents.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: any,\n    embeddings: EmbeddingsInterface,\n    config: CouchbaseSearchVectorStoreArgs\n  ): Promise<CouchbaseSearchVectorStore> {\n    const docs = [];\n\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 await this.fromDocuments(docs, embeddings, config);\n  }\n\n  /**\n   * Delete documents asynchronously from the collection.\n   * This function will attempt to remove each document in the provided list of IDs from the collection.\n   * If an error occurs during the deletion of a document, an error will be thrown with the ID of the document and the error message.\n   * @param ids - An array of document IDs to be deleted from the collection.\n   *\n   * @returns - A promise that resolves when all documents have been attempted to be deleted. If a document could not be deleted, an error is thrown.\n   */\n  public async delete(ids: string[]): Promise<void> {\n    const deleteDocumentsPromises = ids.map((id) =>\n      this._collection.remove(id).catch((err) => {\n        throw new Error(\n          `Error while deleting document - Document Id: ${id}, Error: ${err}`\n        );\n      })\n    );\n    try {\n      await Promise.all(deleteDocumentsPromises);\n    } catch (err) {\n      throw new Error(`Error while deleting documents, Error: ${err}`);\n    }\n  }\n}\n"],"mappings":"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"}