{"version":3,"file":"azure_documentdb.cjs","names":["VectorStore","MongoClient","ObjectId","Document"],"sources":["../src/azure_documentdb.ts"],"sourcesContent":["import {\n  ObjectId,\n  Collection,\n  Document as MongoDBDocument,\n  MongoClient,\n  Db,\n  Filter,\n} from \"mongodb\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport {\n  MaxMarginalRelevanceSearchOptions,\n  VectorStore,\n} from \"@langchain/core/vectorstores\";\nimport { Document, DocumentInterface } from \"@langchain/core/documents\";\nimport { maximalMarginalRelevance } from \"@langchain/core/utils/math\";\nimport { getEnvironmentVariable } from \"@langchain/core/utils/env\";\n\n/** Azure DocumentDB Similarity type. */\nexport const AzureDocumentDBSimilarityType = {\n  /** Cosine similarity */\n  COS: \"COS\",\n  /** Inner - product */\n  IP: \"IP\",\n  /** Euclidian distance */\n  L2: \"L2\",\n} as const;\n\n/** Azure DocumentDB Similarity type. */\nexport type AzureDocumentDBSimilarityType =\n  (typeof AzureDocumentDBSimilarityType)[keyof typeof AzureDocumentDBSimilarityType];\n\n/** Azure DocumentDB Index Options. */\nexport type AzureDocumentDBIndexOptions = {\n  /** Skips automatic index creation. */\n  readonly skipCreate?: boolean;\n\n  readonly indexType?: \"ivf\" | \"hnsw\" | \"diskann\";\n  /** Number of clusters that the inverted file (IVF) index uses to group the vector data. */\n  readonly numLists?: number;\n  /** Number of dimensions for vector similarity. */\n  readonly dimensions?: number;\n  /** Similarity metric to use with the IVF index. */\n  readonly similarity?: AzureDocumentDBSimilarityType;\n  /** The max number of connections per layer with the HNSW index. */\n  readonly m?: number;\n  /** The size of the dynamic candidate list for constructing the graph with the HNSW index. */\n  readonly efConstruction?: number;\n  /** Max number of neighbors with the DiskANN index */\n  readonly maxDegree?: number;\n  /** L value for index building with the DiskANN index */\n  readonly lBuild?: number;\n  /** L value for index searching with the DiskANN index */\n  readonly lSearch?: number;\n};\n\n/** Azure DocumentDB delete Parameters. */\nexport type AzureDocumentDBDeleteParams = {\n  /** List of IDs for the documents to be removed. */\n  readonly ids?: string | string[];\n  /** MongoDB filter object or list of IDs for the documents to be removed. */\n  readonly filter?: Filter<MongoDBDocument>;\n};\n\n/** Configuration options for the `AzureDocumentDBVectorStore` constructor. */\nexport interface AzureDocumentDBConfig {\n  readonly client?: MongoClient;\n  readonly connectionString?: string;\n  readonly databaseName?: string;\n  readonly collectionName?: string;\n  readonly indexName?: string;\n  readonly textKey?: string;\n  readonly embeddingKey?: string;\n  readonly indexOptions?: AzureDocumentDBIndexOptions;\n}\n\n/**\n * Azure DocumentDB vector store.\n * To use this, you should have both:\n * - the `mongodb` NPM package installed\n * - a connection string associated with an Azure DocumentDB cluster\n *\n * You do not need to create a database or collection, it will be created\n * automatically.\n *\n * You also need an index on the collection, which is by default created\n * automatically using the `createIndex` method.\n */\nexport class AzureDocumentDBVectorStore extends VectorStore {\n  get lc_secrets(): { [key: string]: string } {\n    return {\n      connectionString: \"AZURE_DOCUMENTDB_CONNECTION_STRING\",\n    };\n  }\n\n  private connectPromise: Promise<void>;\n\n  private initPromise?: Promise<void>;\n\n  private readonly client: MongoClient | undefined;\n\n  private database: Db;\n\n  private collection: Collection<MongoDBDocument>;\n\n  readonly indexName: string;\n\n  readonly textKey: string;\n\n  readonly embeddingKey: string;\n\n  private readonly indexOptions: AzureDocumentDBIndexOptions;\n\n  /**\n   * Initializes the AzureDocumentDBVectorStore.\n   * Connect the client to the database and create the container, creating them if needed.\n   * @returns A promise that resolves when the AzureDocumentDBVectorStore has been initialized.\n   */\n  initialize: () => Promise<void>;\n\n  _vectorstoreType(): string {\n    return \"azure_documentdb\";\n  }\n\n  constructor(\n    embeddings: EmbeddingsInterface,\n    dbConfig: AzureDocumentDBConfig\n  ) {\n    super(embeddings, dbConfig);\n\n    const connectionString =\n      dbConfig.connectionString ??\n      getEnvironmentVariable(\"AZURE_DOCUMENTDB_CONNECTION_STRING\") ??\n      getEnvironmentVariable(\"AZURE_COSMOSDB_MONGODB_CONNECTION_STRING\");\n\n    if (!dbConfig.client && !connectionString) {\n      throw new Error(\n        \"AzureDocumentDBVectorStore client or connection string must be set.\"\n      );\n    }\n\n    if (!dbConfig.client) {\n      this.client = new MongoClient(connectionString!, {\n        appName: \"langchainjs\",\n      });\n    }\n\n    const client = dbConfig.client || this.client!;\n    const databaseName = dbConfig.databaseName ?? \"documentsDB\";\n    const collectionName = dbConfig.collectionName ?? \"documents\";\n    this.indexName = dbConfig.indexName ?? \"vectorSearchIndex\";\n    this.textKey = dbConfig.textKey ?? \"textContent\";\n    this.embeddingKey = dbConfig.embeddingKey ?? \"vectorContent\";\n    this.indexOptions = dbConfig.indexOptions ?? {};\n\n    // Deferring initialization to the first call to `initialize`\n    this.initialize = () => {\n      if (this.initPromise === undefined) {\n        this.initPromise = this.init(\n          client,\n          databaseName,\n          collectionName\n        ).catch((error) => {\n          console.error(\n            \"Error during AzureDocumentDBVectorStore initialization:\",\n            error\n          );\n        });\n      }\n\n      return this.initPromise;\n    };\n  }\n\n  /**\n   * Checks if the specified index name during instance construction exists\n   * on the collection.\n   * @returns A promise that resolves to a boolean indicating if the index exists.\n   */\n  async checkIndexExists(): Promise<boolean> {\n    await this.initialize();\n    const indexes = await this.collection.listIndexes().toArray();\n    return indexes.some((index) => index.name === this.indexName);\n  }\n\n  /**\n   * Deletes the index specified during instance construction if it exists.\n   * @returns A promise that resolves when the index has been deleted.\n   */\n  async deleteIndex(): Promise<void> {\n    await this.initialize();\n    if (await this.checkIndexExists()) {\n      await this.collection.dropIndex(this.indexName);\n    }\n  }\n\n  /**\n   * Creates an index on the collection with the specified index name during\n   * instance construction.\n   *\n   * Setting the numLists parameter correctly is important for achieving good\n   * accuracy and performance.\n   * Since the vector store uses IVF as the indexing strategy, you should\n   * create the index only after you have loaded a large enough sample\n   * documents to ensure that the centroids for the respective buckets are\n   * fairly distributed.\n   *\n   * We recommend that numLists is set to documentCount/1000 for up to\n   * 1 million documents and to sqrt(documentCount) for more than 1 million\n   * documents.\n   * As the number of items in your database grows, you should tune numLists\n   * to be larger in order to achieve good latency performance for vector\n   * search.\n   *\n   * If you're experimenting with a new scenario or creating a small demo,\n   * you can start with numLists set to 1 to perform a brute-force search\n   * across all vectors.\n   * This should provide you with the most accurate results from the vector\n   * search, however be aware that the search speed and latency will be slow.\n   * After your initial setup, you should go ahead and tune the numLists\n   * parameter using the above guidance.\n   * @param numLists This integer is the number of clusters that the inverted\n   *    file (IVF) index uses to group the vector data.\n   *    We recommend that numLists is set to documentCount/1000 for up to\n   *    1 million documents and to sqrt(documentCount) for more than 1 million\n   *    documents.\n   *    Using a numLists value of 1 is akin to performing brute-force search,\n   *    which has limited performance\n   * @param indexType Index Type for Azure DocumentDB index.\n   * @param dimensions Number of dimensions for vector similarity.\n   *    The maximum number of supported dimensions is 2000.\n   *    If no number is provided, it will be determined automatically by\n   *    embedding a short text.\n   * @param similarity Similarity metric to use with the IVF index.\n   *    Possible options are:\n   *    - AzureDocumentDBSimilarityType.COS (cosine distance)\n   *    - AzureDocumentDBSimilarityType.L2 (Euclidean distance)\n   *    - AzureDocumentDBSimilarityType.IP (inner product)\n   * @returns A promise that resolves when the index has been created.\n   */\n  async createIndex(\n    dimensions: number | undefined = undefined,\n    indexType: \"ivf\" | \"hnsw\" | \"diskann\" = \"ivf\",\n    similarity: AzureDocumentDBSimilarityType = AzureDocumentDBSimilarityType.COS\n  ): Promise<void> {\n    await this.connectPromise;\n\n    let vectorLength = dimensions;\n\n    if (vectorLength === undefined) {\n      const queryEmbedding = await this.embeddings.embedQuery(\"test\");\n      vectorLength = queryEmbedding.length;\n    }\n\n    // eslint-disable-next-line @typescript-eslint/no-explicit-any\n    const cosmosSearchOptions: any = {\n      kind: \"\",\n      similarity,\n      dimensions: vectorLength,\n    };\n\n    if (indexType === \"hnsw\") {\n      cosmosSearchOptions.kind = \"vector-hnsw\";\n      cosmosSearchOptions.m = this.indexOptions.m ?? 16;\n      cosmosSearchOptions.efConstruction =\n        this.indexOptions.efConstruction ?? 200;\n    } else if (indexType === \"diskann\") {\n      cosmosSearchOptions.kind = \"vector-diskann\";\n      cosmosSearchOptions.maxDegree = this.indexOptions.maxDegree ?? 40;\n      cosmosSearchOptions.lBuild = this.indexOptions.lBuild ?? 50;\n      cosmosSearchOptions.lSearch = this.indexOptions.lSearch ?? 40;\n      /** Default to IVF index */\n    } else {\n      cosmosSearchOptions.kind = \"vector-ivf\";\n      cosmosSearchOptions.numLists = this.indexOptions.numLists ?? 100;\n    }\n\n    const createIndexCommands = {\n      createIndexes: this.collection.collectionName,\n      indexes: [\n        {\n          name: this.indexName,\n          key: { [this.embeddingKey]: \"cosmosSearch\" },\n          cosmosSearchOptions,\n        },\n      ],\n    };\n\n    await this.database.command(createIndexCommands);\n  }\n\n  /**\n   * Removes specified documents from the AzureDocumentDBVectorStore.\n   * If no IDs or filter are specified, all documents will be removed.\n   * @param params Parameters for the delete operation.\n   * @returns A promise that resolves when the documents have been removed.\n   */\n  async delete(\n    params: AzureDocumentDBDeleteParams | string[] = {}\n  ): Promise<void> {\n    await this.initialize();\n\n    let ids: string | string[] | undefined;\n    let filter: AzureDocumentDBDeleteParams[\"filter\"];\n    if (Array.isArray(params)) {\n      ids = params;\n    } else {\n      ids = params.ids;\n      filter = params.filter;\n    }\n    const idsArray = Array.isArray(ids) ? ids : [ids];\n    const deleteIds = ids && idsArray.length > 0 ? idsArray : undefined;\n    let deleteFilter = filter ?? {};\n\n    if (deleteIds) {\n      const objectIds = deleteIds.map((id) => new ObjectId(id));\n      deleteFilter = { _id: { $in: objectIds }, ...deleteFilter };\n    }\n\n    await this.collection.deleteMany(deleteFilter);\n  }\n\n  /**\n   * Closes any newly instantiated Azure DocumentDB client.\n   * If the client was passed in the constructor, it will not be closed.\n   * @returns A promise that resolves when any newly instantiated Azure\n   *     DocumentDB client has been closed.\n   */\n  async close(): Promise<void> {\n    if (this.client) {\n      await this.client.close();\n    }\n  }\n\n  /**\n   * Method for adding vectors to the AzureDocumentDBVectorStore.\n   * @param vectors Vectors to be added.\n   * @param documents Corresponding documents to be added.\n   * @returns A promise that resolves to the added documents IDs.\n   */\n  async addVectors(\n    vectors: number[][],\n    documents: DocumentInterface[]\n  ): Promise<string[]> {\n    const docs = vectors.map((embedding, idx) => ({\n      [this.textKey]: documents[idx].pageContent,\n      [this.embeddingKey]: embedding,\n      ...documents[idx].metadata,\n    }));\n    await this.initialize();\n    const result = await this.collection.insertMany(docs);\n    return Object.values(result.insertedIds).map((id) => String(id));\n  }\n\n  /**\n   * Method for adding documents to the AzureDocumentDBVectorStore. It first converts\n   * the documents to texts and then adds them as vectors.\n   * @param documents The documents to add.\n   * @returns A promise that resolves to the added documents IDs.\n   */\n  async addDocuments(documents: DocumentInterface[]): Promise<string[]> {\n    const texts = documents.map(({ pageContent }) => pageContent);\n    return this.addVectors(\n      await this.embeddings.embedDocuments(texts),\n      documents\n    );\n  }\n\n  /**\n   * Method that performs a similarity search on the vectors stored in the\n   * collection. It returns a list of documents and their corresponding\n   * similarity scores.\n   * @param queryVector Query vector for the similarity search.\n   * @param k=4 Number of nearest neighbors to return.\n   * @returns Promise that resolves to a list of documents and their corresponding similarity scores.\n   */\n  async similaritySearchVectorWithScore(\n    queryVector: number[],\n    k: number,\n    indexType?: \"ivf\" | \"hnsw\" | \"diskann\"\n  ): Promise<[Document, number][]> {\n    await this.initialize();\n\n    const pipeline = [\n      {\n        $search: {\n          cosmosSearch: {\n            vector: queryVector,\n            path: this.embeddingKey,\n            k: k ?? 4,\n            ...(indexType === \"diskann\"\n              ? { lSearch: this.indexOptions.lSearch ?? 40 }\n              : {}),\n          },\n          returnStoredSource: true,\n        },\n      },\n      {\n        $project: {\n          similarityScore: { $meta: \"searchScore\" },\n          document: \"$$ROOT\",\n        },\n      },\n    ];\n    const results = await this.collection\n      .aggregate(pipeline)\n      .map<[Document, number]>((result) => {\n        const { similarityScore: score, document } = result;\n        const text = document[this.textKey];\n        return [new Document({ pageContent: text, metadata: document }), score];\n      });\n\n    return results.toArray();\n  }\n\n  /**\n   * Return documents selected using the maximal marginal relevance.\n   * Maximal marginal relevance optimizes for similarity to the query AND\n   * diversity among selected documents.\n   * @param query Text to look up documents similar to.\n   * @param options.k Number of documents to return.\n   * @param options.fetchK=20 Number of documents to fetch before passing to\n   *     the MMR algorithm.\n   * @param options.lambda=0.5 Number between 0 and 1 that determines the\n   *     degree of diversity among the results, where 0 corresponds to maximum\n   *     diversity and 1 to minimum diversity.\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\n  async maxMarginalRelevanceSearch(\n    query: string,\n    options: MaxMarginalRelevanceSearchOptions<this[\"FilterType\"]>,\n    indexType: \"ivf\" | \"hnsw\" | \"diskann\"\n  ): Promise<Document[]>;\n\n  async maxMarginalRelevanceSearch(\n    query: string,\n    options: MaxMarginalRelevanceSearchOptions<this[\"FilterType\"]>,\n    indexType?: \"ivf\" | \"hnsw\" | \"diskann\"\n  ): Promise<Document[]> {\n    const { k, fetchK = 20, lambda = 0.5 } = options;\n\n    const queryEmbedding = await this.embeddings.embedQuery(query);\n    const docs = await this.similaritySearchVectorWithScore(\n      queryEmbedding,\n      fetchK,\n      indexType\n    );\n    const embeddingList = docs.map((doc) => doc[0].metadata[this.embeddingKey]);\n\n    // Re-rank the results using MMR\n    const mmrIndexes = maximalMarginalRelevance(\n      queryEmbedding,\n      embeddingList,\n      lambda,\n      k\n    );\n\n    const mmrDocs = mmrIndexes.map((index) => docs[index][0]);\n    return mmrDocs;\n  }\n\n  /**\n   * Initializes the AzureDocumentDBVectorStore by connecting to the database.\n   * @param client The MongoClient to use for connecting to the database.\n   * @param databaseName The name of the database to use.\n   * @param collectionName The name of the collection to use.\n   * @returns A promise that resolves when the AzureDocumentDBVectorStore has been initialized.\n   */\n  private async init(\n    client: MongoClient,\n    databaseName: string,\n    collectionName: string\n  ): Promise<void> {\n    this.connectPromise = (async () => {\n      await client.connect();\n      this.database = client.db(databaseName);\n      this.collection = this.database.collection(collectionName);\n    })();\n\n    // Unless skipCreate is set, create the index\n    // This operation is no-op if the index already exists\n    if (!this.indexOptions.skipCreate) {\n      const indexType = this.indexOptions.indexType || \"ivf\";\n      await this.createIndex(\n        this.indexOptions.dimensions,\n        indexType,\n        this.indexOptions.similarity\n      );\n    }\n  }\n\n  /**\n   * Static method to create an instance of AzureDocumentDBVectorStore from a\n   * list of texts. It first converts the texts to vectors and then adds\n   * them to the collection.\n   * @param texts List of texts to be converted to vectors.\n   * @param metadatas Metadata for the texts.\n   * @param embeddings Embeddings to be used for conversion.\n   * @param dbConfig Database configuration for Azure DocumentDB.\n   * @returns Promise that resolves to a new instance of AzureDocumentDBVectorStore.\n   */\n  static async fromTexts(\n    texts: string[],\n    metadatas: object[] | object,\n    embeddings: EmbeddingsInterface,\n    dbConfig: AzureDocumentDBConfig\n  ): Promise<AzureDocumentDBVectorStore> {\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 AzureDocumentDBVectorStore.fromDocuments(docs, embeddings, dbConfig);\n  }\n\n  /**\n   * Static method to create an instance of AzureDocumentDBVectorStore from a\n   * list of documents. It first converts the documents to vectors and then\n   * adds them to the collection.\n   * @param docs List of documents to be converted to vectors.\n   * @param embeddings Embeddings to be used for conversion.\n   * @param dbConfig Database configuration for Azure DocumentDB.\n   * @returns Promise that resolves to a new instance of AzureDocumentDBVectorStore.\n   */\n  static async fromDocuments(\n    docs: Document[],\n    embeddings: EmbeddingsInterface,\n    dbConfig: AzureDocumentDBConfig\n  ): Promise<AzureDocumentDBVectorStore> {\n    const instance = new this(embeddings, dbConfig);\n    await instance.addDocuments(docs);\n    return instance;\n  }\n}\n\n// ============================================================================\n// Deprecated aliases for backwards compatibility\n// ============================================================================\n\n/**\n * @deprecated Use `AzureDocumentDBSimilarityType` instead. This alias will be removed in a future version.\n */\nexport const AzureCosmosDBMongoDBSimilarityType = AzureDocumentDBSimilarityType;\n\n/**\n * @deprecated Use `AzureDocumentDBSimilarityType` instead. This alias will be removed in a future version.\n */\nexport type AzureCosmosDBMongoDBSimilarityType = AzureDocumentDBSimilarityType;\n\n/**\n * @deprecated Use `AzureDocumentDBIndexOptions` instead. This alias will be removed in a future version.\n */\nexport type AzureCosmosDBMongoDBIndexOptions = AzureDocumentDBIndexOptions;\n\n/**\n * @deprecated Use `AzureDocumentDBDeleteParams` instead. This alias will be removed in a future version.\n */\nexport type AzureCosmosDBMongoDBDeleteParams = AzureDocumentDBDeleteParams;\n\n/**\n * @deprecated Use `AzureDocumentDBConfig` instead. This alias will be removed in a future version.\n */\nexport type AzureCosmosDBMongoDBConfig = AzureDocumentDBConfig;\n\n/**\n * @deprecated Use `AzureDocumentDBVectorStore` instead. This alias will be removed in a future version.\n */\nexport const AzureCosmosDBMongoDBVectorStore = AzureDocumentDBVectorStore;\n\n/**\n * @deprecated Use `AzureDocumentDBVectorStore` instead. This alias will be removed in a future version.\n */\nexport type AzureCosmosDBMongoDBVectorStore = AzureDocumentDBVectorStore;\n"],"mappings":"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"}