UNPKG

@langchain/community

Version:
1 lines • 26.7 kB
{"version":3,"file":"singlestore.cjs","names":["OrderingDirective: Record<DistanceMetrics, string>","config: SingleStoreVectorStoreConfig","newOptions: ConnectionOptions","result: ConnectionOptions","VectorStore","embeddings: EmbeddingsInterface","config: SearchConfig","documents: Document[]","vectors: number[][]","query: string","vector: number[]","k: number","filter?: Metadata","whereArgs: string[]","record: Metadata","argList: string[]","whereTokens: string[]","whereClauses: string[]","result: [Document, number][]","Document","k?: number","_callbacks?: Callbacks | undefined","query: number[]","texts: string[]","metadatas: object[]","dbConfig: SingleStoreVectorStoreConfig","docs: Document[]"],"sources":["../../src/vectorstores/singlestore.ts"],"sourcesContent":["import type {\n Pool,\n RowDataPacket,\n OkPacket,\n ResultSetHeader,\n FieldPacket,\n PoolOptions,\n} from \"mysql2/promise\";\nimport { format } from \"mysql2\";\nimport { createPool } from \"mysql2/promise\";\nimport type { EmbeddingsInterface } from \"@langchain/core/embeddings\";\nimport { VectorStore } from \"@langchain/core/vectorstores\";\nimport { Document, DocumentInterface } from \"@langchain/core/documents\";\nimport { Callbacks } from \"@langchain/core/callbacks/manager\";\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Metadata = Record<string, any>;\n\nexport type DistanceMetrics = \"DOT_PRODUCT\" | \"EUCLIDEAN_DISTANCE\";\n\nexport type SearchStrategy =\n | \"VECTOR_ONLY\"\n | \"TEXT_ONLY\"\n | \"FILTER_BY_TEXT\"\n | \"FILTER_BY_VECTOR\"\n | \"WEIGHTED_SUM\";\n\nconst OrderingDirective: Record<DistanceMetrics, string> = {\n DOT_PRODUCT: \"DESC\",\n EUCLIDEAN_DISTANCE: \"\",\n};\n\nexport interface ConnectionOptions extends PoolOptions {}\n\ntype ConnectionWithUri = {\n connectionOptions?: never;\n connectionURI: string;\n};\n\ntype ConnectionWithOptions = {\n connectionURI?: never;\n connectionOptions: ConnectionOptions;\n};\n\ntype ConnectionConfig = ConnectionWithUri | ConnectionWithOptions;\n\ntype SearchConfig = {\n searchStrategy?: SearchStrategy;\n filterThreshold?: number;\n textWeight?: number;\n vectorWeight?: number;\n vectorselectCountMultiplier?: number;\n};\n\nexport type SingleStoreVectorStoreConfig = ConnectionConfig & {\n tableName?: string;\n idColumnName?: string;\n contentColumnName?: string;\n vectorColumnName?: string;\n metadataColumnName?: string;\n distanceMetric?: DistanceMetrics;\n useVectorIndex?: boolean;\n vectorIndexName?: string;\n vectorIndexOptions?: Metadata;\n vectorSize?: number;\n useFullTextIndex?: boolean;\n searchConfig?: SearchConfig;\n};\n\n/**\n * Adds the connect attributes to the connection options.\n * @param config A SingleStoreVectorStoreConfig object.\n */\nfunction withConnectAttributes(\n config: SingleStoreVectorStoreConfig\n): ConnectionOptions {\n let newOptions: ConnectionOptions = {};\n if (config.connectionURI) {\n newOptions = {\n uri: config.connectionURI,\n };\n } else if (config.connectionOptions) {\n newOptions = {\n ...config.connectionOptions,\n };\n }\n const result: ConnectionOptions = {\n ...newOptions,\n connectAttributes: {\n ...newOptions.connectAttributes,\n },\n };\n\n if (!result.connectAttributes) {\n result.connectAttributes = {};\n }\n\n result.connectAttributes = {\n ...result.connectAttributes,\n _connector_name: \"langchain js sdk\",\n _connector_version: \"2.0.0\",\n _driver_name: \"Node-MySQL-2\",\n };\n\n return result;\n}\n\n/**\n * Class for interacting with SingleStoreDB, a high-performance\n * distributed SQL database. It provides vector storage and vector\n * functions.\n */\nexport class SingleStoreVectorStore extends VectorStore {\n connectionPool: Pool;\n\n tableName: string;\n\n idColumnName: string;\n\n contentColumnName: string;\n\n vectorColumnName: string;\n\n metadataColumnName: string;\n\n distanceMetric: DistanceMetrics;\n\n useVectorIndex: boolean;\n\n vectorIndexName: string;\n\n vectorIndexOptions: Metadata;\n\n vectorSize: number;\n\n useFullTextIndex: boolean;\n\n searchConfig: SearchConfig;\n\n _vectorstoreType(): string {\n return \"singlestore\";\n }\n\n constructor(\n embeddings: EmbeddingsInterface,\n config: SingleStoreVectorStoreConfig\n ) {\n super(embeddings, config);\n this.connectionPool = createPool(withConnectAttributes(config));\n this.tableName = config.tableName ?? \"embeddings\";\n this.idColumnName = config.idColumnName ?? \"id\";\n this.contentColumnName = config.contentColumnName ?? \"content\";\n this.vectorColumnName = config.vectorColumnName ?? \"vector\";\n this.metadataColumnName = config.metadataColumnName ?? \"metadata\";\n this.distanceMetric = config.distanceMetric ?? \"DOT_PRODUCT\";\n this.useVectorIndex = config.useVectorIndex ?? false;\n this.vectorIndexName = config.vectorIndexName ?? \"\";\n this.vectorIndexOptions = config.vectorIndexOptions ?? {};\n this.vectorSize = config.vectorSize ?? 1536;\n this.useFullTextIndex = config.useFullTextIndex ?? false;\n this.searchConfig = config.searchConfig ?? {\n searchStrategy: \"VECTOR_ONLY\",\n filterThreshold: 1.0,\n textWeight: 0.5,\n vectorWeight: 0.5,\n vectorselectCountMultiplier: 10,\n };\n }\n\n /**\n * Creates a new table in the SingleStoreDB database if it does not\n * already exist.\n */\n async createTableIfNotExists(): Promise<void> {\n let fullTextIndex = \"\";\n if (this.useFullTextIndex) {\n fullTextIndex = `, FULLTEXT(${this.contentColumnName})`;\n }\n if (this.useVectorIndex) {\n let vectorIndexOptions = \"\";\n if (Object.keys(this.vectorIndexOptions).length > 0) {\n vectorIndexOptions = `INDEX_OPTIONS '${JSON.stringify(\n this.vectorIndexOptions\n )}'`;\n }\n await this.connectionPool\n .execute(`CREATE TABLE IF NOT EXISTS ${this.tableName} (\n ${this.idColumnName} BIGINT AUTO_INCREMENT PRIMARY KEY,\n ${this.contentColumnName} LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,\n ${this.vectorColumnName} VECTOR(${this.vectorSize}, F32) NOT NULL,\n ${this.metadataColumnName} JSON,\n VECTOR INDEX ${this.vectorIndexName} (${this.vectorColumnName}) ${vectorIndexOptions}\n ${fullTextIndex});`);\n } else {\n await this.connectionPool\n .execute(`CREATE TABLE IF NOT EXISTS ${this.tableName} (\n ${this.idColumnName} BIGINT AUTO_INCREMENT PRIMARY KEY,\n ${this.contentColumnName} LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci,\n ${this.vectorColumnName} BLOB,\n ${this.metadataColumnName} JSON\n ${fullTextIndex});`);\n }\n }\n\n /**\n * Ends the connection to the SingleStoreDB database.\n */\n async end(): Promise<void> {\n return this.connectionPool.end();\n }\n\n /**\n * Sets the search configuration for the SingleStoreVectorStore instance.\n * @param config A SearchConfig object.\n */\n async setSearchConfig(config: SearchConfig): Promise<void> {\n this.searchConfig = {\n searchStrategy: config.searchStrategy ?? \"VECTOR_ONLY\",\n filterThreshold: config.filterThreshold ?? 1.0,\n textWeight: config.textWeight ?? 0.5,\n vectorWeight: config.vectorWeight ?? 0.5,\n vectorselectCountMultiplier: config.vectorselectCountMultiplier ?? 10,\n };\n }\n\n /**\n * Adds new documents to the SingleStoreDB database.\n * @param documents An array of Document objects.\n */\n async addDocuments(documents: Document[]): Promise<void> {\n const texts = documents.map(({ pageContent }) => pageContent);\n const vectors = await this.embeddings.embedDocuments(texts);\n return this.addVectors(vectors, documents);\n }\n\n /**\n * Adds new vectors to the SingleStoreDB database.\n * @param vectors An array of vectors.\n * @param documents An array of Document objects.\n */\n async addVectors(vectors: number[][], documents: Document[]): Promise<void> {\n await this.createTableIfNotExists();\n const { tableName } = this;\n\n await Promise.all(\n vectors.map(async (vector, idx) => {\n try {\n await this.connectionPool.query(\n format(\n `INSERT INTO ${tableName}(\n ${this.contentColumnName},\n ${this.vectorColumnName},\n ${this.metadataColumnName})\n VALUES (?, JSON_ARRAY_PACK('[?]'), ?);`,\n [\n documents[idx].pageContent,\n vector,\n JSON.stringify(documents[idx].metadata),\n ]\n )\n );\n } catch (error) {\n console.error(`Error adding vector at index ${idx}:`, error);\n }\n })\n );\n if (this.useFullTextIndex || this.useVectorIndex) {\n await this.connectionPool.query(`OPTIMIZE TABLE ${tableName} FLUSH;`);\n }\n }\n\n /**\n *\n * Performs a similarity search on the texts stored in the SingleStoreDB\n * using the specified search strategy and distance metric.\n * @param query A string representing the query text.\n * @param vector An array of numbers representing the query vector.\n * @param k The number of nearest neighbors to return.\n * @param filter Optional metadata to filter the texts by.\n * @returns Top matching documents with score\n */\n async similaritySearchTextAndVectorWithScore(\n query: string,\n vector: number[],\n k: number,\n filter?: Metadata\n ): Promise<[Document, number][]> {\n if (!this.searchConfig.searchStrategy) {\n throw new Error(\"Search strategy is required.\");\n }\n if (\n this.searchConfig.searchStrategy !== \"VECTOR_ONLY\" &&\n !this.useFullTextIndex\n ) {\n throw new Error(\n \"Full text index is required for text-based search strategies.\"\n );\n }\n if (\n (this.searchConfig.searchStrategy === \"FILTER_BY_TEXT\" ||\n this.searchConfig.searchStrategy === \"FILTER_BY_VECTOR\") &&\n !this.searchConfig.filterThreshold &&\n this.searchConfig.filterThreshold !== 0\n ) {\n throw new Error(\n \"Filter threshold is required for filter-based search strategies.\"\n );\n }\n if (\n this.searchConfig.searchStrategy === \"WEIGHTED_SUM\" &&\n ((!this.searchConfig.textWeight && this.searchConfig.textWeight !== 0) ||\n (!this.searchConfig.vectorWeight &&\n this.searchConfig.vectorWeight !== 0) ||\n (!this.searchConfig.vectorselectCountMultiplier &&\n this.searchConfig.vectorselectCountMultiplier !== 0))\n ) {\n throw new Error(\n \"Text and vector weight and vector select count multiplier are required for weighted sum search strategy.\"\n );\n }\n if (\n this.searchConfig.searchStrategy === \"WEIGHTED_SUM\" &&\n this.distanceMetric !== \"DOT_PRODUCT\"\n ) {\n throw new Error(\n \"Weighted sum search strategy is only available for DOT_PRODUCT distance metric.\"\n );\n }\n const filterThreshold = this.searchConfig.filterThreshold ?? 1.0;\n // build the where clause from filter\n const whereArgs: string[] = [];\n const buildWhereClause = (record: Metadata, argList: string[]): string => {\n const whereTokens: string[] = [];\n for (const key in record)\n if (record[key] !== undefined) {\n if (\n typeof record[key] === \"object\" &&\n record[key] != null &&\n !Array.isArray(record[key])\n ) {\n whereTokens.push(\n buildWhereClause(record[key], argList.concat([key]))\n );\n } else {\n whereTokens.push(\n `JSON_EXTRACT_JSON(${this.metadataColumnName}, `.concat(\n Array.from({ length: argList.length + 1 }, () => \"?\").join(\n \", \"\n ),\n \") = ?\"\n )\n );\n whereArgs.push(...argList, key, JSON.stringify(record[key]));\n }\n }\n return whereTokens.join(\" AND \");\n };\n const filterByTextClause = (): string => {\n whereArgs.push(query, filterThreshold.toString());\n return `MATCH (${this.contentColumnName}) AGAINST (?) > ?`;\n };\n const filterByVectorClause = (): string => {\n whereArgs.push(JSON.stringify(vector), filterThreshold.toString());\n return this.distanceMetric === \"DOT_PRODUCT\"\n ? `${this.distanceMetric}(${this.vectorColumnName}, JSON_ARRAY_PACK(?)) > ?`\n : `${this.distanceMetric}(${this.vectorColumnName}, JSON_ARRAY_PACK(?)) < ?`;\n };\n const whereClauses: string[] = [];\n if (filter) {\n whereClauses.push(buildWhereClause(filter, []));\n }\n if (this.searchConfig.searchStrategy === \"FILTER_BY_TEXT\") {\n whereClauses.push(filterByTextClause());\n }\n if (this.searchConfig.searchStrategy === \"FILTER_BY_VECTOR\") {\n whereClauses.push(filterByVectorClause());\n }\n const whereClause =\n whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n let queryText = \"\";\n switch (this.searchConfig.searchStrategy) {\n case \"TEXT_ONLY\":\n case \"FILTER_BY_VECTOR\":\n queryText = format(\n `SELECT ${this.contentColumnName}, ${this.metadataColumnName},\n MATCH (${this.contentColumnName}) AGAINST (?) as __score\n FROM ${this.tableName} ${whereClause} ORDER BY __score DESC LIMIT ?;`,\n [query, ...whereArgs, k]\n );\n break;\n case \"VECTOR_ONLY\":\n case \"FILTER_BY_TEXT\":\n queryText = format(\n `SELECT ${this.contentColumnName}, ${this.metadataColumnName},\n ${this.distanceMetric}(${\n this.vectorColumnName\n }, JSON_ARRAY_PACK('[?]')) as __score\n FROM ${this.tableName} ${whereClause} ORDER BY __score ${\n OrderingDirective[this.distanceMetric]\n } LIMIT ?;`,\n [vector, ...whereArgs, k]\n );\n break;\n case \"WEIGHTED_SUM\":\n queryText = format(\n `SELECT ${this.contentColumnName}, ${\n this.metadataColumnName\n }, __score1 * ? + __score2 * ? as __score\n FROM (\n SELECT ${this.idColumnName}, ${this.contentColumnName}, ${\n this.metadataColumnName\n }, MATCH (${this.contentColumnName}) AGAINST (?) as __score1 \n FROM ${this.tableName} ${whereClause}) r1 FULL OUTER JOIN (\n SELECT ${this.idColumnName}, ${this.distanceMetric}(${\n this.vectorColumnName\n }, JSON_ARRAY_PACK('[?]')) as __score2\n FROM ${this.tableName} ${whereClause} ORDER BY __score2 ${\n OrderingDirective[this.distanceMetric]\n } LIMIT ?\n ) r2 ON r1.${this.idColumnName} = r2.${\n this.idColumnName\n } ORDER BY __score ${OrderingDirective[this.distanceMetric]} LIMIT ?`,\n [\n this.searchConfig.textWeight,\n this.searchConfig.vectorWeight,\n query,\n ...whereArgs,\n vector,\n ...whereArgs,\n k * (this.searchConfig.vectorselectCountMultiplier ?? 10),\n k,\n ]\n );\n break;\n default:\n throw new Error(\"Invalid search strategy.\");\n }\n const [rows]: [\n (\n | RowDataPacket[]\n | RowDataPacket[][]\n | OkPacket\n | OkPacket[]\n | ResultSetHeader\n ),\n FieldPacket[],\n ] = await this.connectionPool.query(queryText);\n const result: [Document, number][] = [];\n for (const row of rows as RowDataPacket[]) {\n const rowData = row as unknown as Record<string, unknown>;\n result.push([\n new Document({\n pageContent: rowData[this.contentColumnName] as string,\n metadata: rowData[this.metadataColumnName] as Record<string, unknown>,\n }),\n Number(rowData.score),\n ]);\n }\n return result;\n }\n\n /**\n * Performs a similarity search on the texts stored in the SingleStoreDB\n * @param query A string representing the query text.\n * @param k The number of nearest neighbors to return. By default, it is 4.\n * @param filter Optional metadata to filter the texts by.\n * @param _callbacks - Callbacks object, not used in this implementation.\n * @returns Top matching documents\n */\n async similaritySearch(\n query: string,\n k?: number,\n filter?: Metadata,\n _callbacks?: Callbacks | undefined\n ): Promise<DocumentInterface<Metadata>[]> {\n // @typescript-eslint/no-explicit-any\n const queryVector = await this.embeddings.embedQuery(query);\n return this.similaritySearchTextAndVectorWithScore(\n query,\n queryVector,\n k ?? 4,\n filter\n ).then((result) => result.map(([doc]) => doc));\n }\n\n /**\n * Performs a similarity search on the texts stored in the SingleStoreDB\n * @param query A string representing the query text.\n * @param k The number of nearest neighbors to return. By default, it is 4.\n * @param filter Optional metadata to filter the texts by.\n * @param _callbacks\n * @returns Top matching documents with score\n */\n async similaritySearchWithScore(\n query: string,\n k?: number,\n filter?: Metadata,\n _callbacks?: Callbacks | undefined\n ): Promise<[DocumentInterface<Metadata>, number][]> {\n // @typescript-eslint/no-explicit-any\n const queryVector = await this.embeddings.embedQuery(query);\n return this.similaritySearchTextAndVectorWithScore(\n query,\n queryVector,\n k ?? 4,\n filter\n );\n }\n\n /**\n * Performs a similarity search on the vectors stored in the SingleStoreDB\n * database.\n * @param query An array of numbers representing the query vector.\n * @param k The number of nearest neighbors to return.\n * @param filter Optional metadata to filter the vectors by.\n * @returns Top matching vectors with score\n */\n async similaritySearchVectorWithScore(\n query: number[],\n k: number,\n filter?: Metadata\n ): Promise<[Document, number][]> {\n if (this.searchConfig.searchStrategy !== \"VECTOR_ONLY\") {\n throw new Error(\n \"similaritySearchVectorWithScore is only available for VECTOR_ONLY search strategy.\"\n );\n }\n return this.similaritySearchTextAndVectorWithScore(\"\", query, k, filter);\n }\n\n /**\n * Creates a new instance of the SingleStoreVectorStore class from a list\n * of texts.\n * @param texts An array of strings.\n * @param metadatas An array of metadata objects.\n * @param embeddings An Embeddings object.\n * @param dbConfig A SingleStoreVectorStoreConfig object.\n * @returns A new SingleStoreVectorStore instance\n */\n static async fromTexts(\n texts: string[],\n metadatas: object[],\n embeddings: EmbeddingsInterface,\n dbConfig: SingleStoreVectorStoreConfig\n ): Promise<SingleStoreVectorStore> {\n const docs = texts.map((text, idx) => {\n const metadata = Array.isArray(metadatas) ? metadatas[idx] : metadatas;\n return new Document({\n pageContent: text,\n metadata,\n });\n });\n return SingleStoreVectorStore.fromDocuments(docs, embeddings, dbConfig);\n }\n\n /**\n * Creates a new instance of the SingleStoreVectorStore class from a list\n * of Document objects.\n * @param docs An array of Document objects.\n * @param embeddings An Embeddings object.\n * @param dbConfig A SingleStoreVectorStoreConfig object.\n * @returns A new SingleStoreVectorStore instance\n */\n static async fromDocuments(\n docs: Document[],\n embeddings: EmbeddingsInterface,\n dbConfig: SingleStoreVectorStoreConfig\n ): Promise<SingleStoreVectorStore> {\n const instance = new this(embeddings, dbConfig);\n await instance.addDocuments(docs);\n return instance;\n }\n}\n"],"mappings":"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"}