diff --git a/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBAtlas.ts b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBAtlas.ts new file mode 100644 index 000000000..a0699f6bd --- /dev/null +++ b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBAtlas.ts @@ -0,0 +1,194 @@ +import { flatten } from 'lodash' +import { MongoClient } from 'mongodb' +import { MongoDBAtlasVectorSearch } from 'langchain/vectorstores/mongodb_atlas' +import { Embeddings } from 'langchain/embeddings/base' +import { Document } from 'langchain/document' +import { ICommonObject, INode, INodeData, INodeOutputsValue, INodeParams } from '../../../src/Interface' +import { getBaseClasses, getCredentialData, getCredentialParam } from '../../../src/utils' + +class MongoDBAtlas_VectorStores implements INode { + label: string + name: string + version: number + description: string + type: string + icon: string + category: string + badge: string + baseClasses: string[] + inputs: INodeParams[] + credential: INodeParams + outputs: INodeOutputsValue[] + + constructor() { + this.label = 'MongoDB Atlas' + this.name = 'mongoDBAtlas' + this.version = 1.0 + this.description = `Upsert embedded data and perform similarity search upon query using MongoDB Atlas, a managed cloud mongodb database` + this.type = 'MongoDB Atlas' + this.icon = 'mongodb.png' + this.category = 'Vector Stores' + this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever'] + this.badge = 'NEW' + this.credential = { + label: 'Connect Credential', + name: 'credential', + type: 'credential', + credentialNames: ['mongoDBUrlApi'] + } + this.inputs = [ + { + label: 'Document', + name: 'document', + type: 'Document', + list: true, + optional: true + }, + { + label: 'Embeddings', + name: 'embeddings', + type: 'Embeddings' + }, + { + label: 'Database', + name: 'databaseName', + placeholder: '', + type: 'string' + }, + { + label: 'Collection Name', + name: 'collectionName', + placeholder: '', + type: 'string' + }, + { + label: 'Index Name', + name: 'indexName', + placeholder: '', + type: 'string' + }, + { + label: 'Content Field', + name: 'textKey', + description: 'Name of the field (column) that contains the actual content', + type: 'string', + default: 'text', + additionalParams: true, + optional: true + }, + { + label: 'Embedded Field', + name: 'embeddingKey', + description: 'Name of the field (column) that contains the Embedding', + type: 'string', + default: 'embedding', + additionalParams: true, + optional: true + }, + { + label: 'Top K', + name: 'topK', + description: 'Number of top results to fetch. Default to 4', + placeholder: '4', + type: 'number', + additionalParams: true, + optional: true + } + ] + this.outputs = [ + { + label: 'MongoDB Retriever', + name: 'retriever', + baseClasses: this.baseClasses + }, + { + label: 'MongoDB Vector Store', + name: 'vectorStore', + baseClasses: [this.type, ...getBaseClasses(MongoDBAtlasVectorSearch)] + } + ] + } + + //@ts-ignore + vectorStoreMethods = { + async upsert(nodeData: INodeData, options: ICommonObject): Promise { + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + const databaseName = nodeData.inputs?.databaseName as string + const collectionName = nodeData.inputs?.collectionName as string + const indexName = nodeData.inputs?.indexName as string + let textKey = nodeData.inputs?.textKey as string + let embeddingKey = nodeData.inputs?.embeddingKey as string + const embeddings = nodeData.inputs?.embeddings as Embeddings + + let mongoDBConnectUrl = getCredentialParam('mongoDBConnectUrl', credentialData, nodeData) + + const docs = nodeData.inputs?.document as Document[] + + const flattenDocs = docs && docs.length ? flatten(docs) : [] + const finalDocs = [] + for (let i = 0; i < flattenDocs.length; i += 1) { + if (flattenDocs[i] && flattenDocs[i].pageContent) { + const document = new Document(flattenDocs[i]) + finalDocs.push(document) + } + } + + const mongoClient = new MongoClient(mongoDBConnectUrl) + const collection = mongoClient.db(databaseName).collection(collectionName) + + if (!textKey || textKey === '') textKey = 'text' + if (!embeddingKey || embeddingKey === '') embeddingKey = 'embedding' + + const mongoDBAtlasVectorSearch = new MongoDBAtlasVectorSearch(embeddings, { + collection, + indexName, + textKey, + embeddingKey + }) + + try { + await mongoDBAtlasVectorSearch.addDocuments(finalDocs) + } catch (e) { + throw new Error(e) + } + } + } + + async init(nodeData: INodeData, _: string, options: ICommonObject): Promise { + const credentialData = await getCredentialData(nodeData.credential ?? '', options) + const databaseName = nodeData.inputs?.databaseName as string + const collectionName = nodeData.inputs?.collectionName as string + const indexName = nodeData.inputs?.indexName as string + let textKey = nodeData.inputs?.textKey as string + let embeddingKey = nodeData.inputs?.embeddingKey as string + const embeddings = nodeData.inputs?.embeddings as Embeddings + const topK = nodeData.inputs?.topK as string + const k = topK ? parseFloat(topK) : 4 + const output = nodeData.outputs?.output as string + + let mongoDBConnectUrl = getCredentialParam('mongoDBConnectUrl', credentialData, nodeData) + + const mongoClient = new MongoClient(mongoDBConnectUrl) + const collection = mongoClient.db(databaseName).collection(collectionName) + + if (!textKey || textKey === '') textKey = 'text' + if (!embeddingKey || embeddingKey === '') embeddingKey = 'embedding' + + const vectorStore = new MongoDBAtlasVectorSearch(embeddings, { + collection, + indexName, + textKey, + embeddingKey + }) + + if (output === 'retriever') { + return vectorStore.asRetriever(k) + } else if (output === 'vectorStore') { + ;(vectorStore as any).k = k + return vectorStore + } + return vectorStore + } +} + +module.exports = { nodeClass: MongoDBAtlas_VectorStores } diff --git a/packages/components/nodes/vectorstores/MongoDB/MongoDBSearchBase.ts b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBSearchBase.ts similarity index 98% rename from packages/components/nodes/vectorstores/MongoDB/MongoDBSearchBase.ts rename to packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBSearchBase.ts index e9ef8e9a1..95930e4a0 100644 --- a/packages/components/nodes/vectorstores/MongoDB/MongoDBSearchBase.ts +++ b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDBSearchBase.ts @@ -22,6 +22,7 @@ export abstract class MongoDBSearchBase { type: string icon: string category: string + badge: string baseClasses: string[] inputs: INodeParams[] credential: INodeParams @@ -33,6 +34,7 @@ export abstract class MongoDBSearchBase { this.icon = 'mongodb.png' this.category = 'Vector Stores' this.baseClasses = [this.type, 'VectorStoreRetriever', 'BaseRetriever'] + this.badge = 'DEPRECATING' this.credential = { label: 'Connect Credential', name: 'credential', diff --git a/packages/components/nodes/vectorstores/MongoDB/MongoDB_Existing.ts b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDB_Existing.ts similarity index 100% rename from packages/components/nodes/vectorstores/MongoDB/MongoDB_Existing.ts rename to packages/components/nodes/vectorstores/MongoDBAtlas/MongoDB_Existing.ts diff --git a/packages/components/nodes/vectorstores/MongoDB/MongoDB_Upsert.ts b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDB_Upsert.ts similarity index 97% rename from packages/components/nodes/vectorstores/MongoDB/MongoDB_Upsert.ts rename to packages/components/nodes/vectorstores/MongoDBAtlas/MongoDB_Upsert.ts index 7d22f0352..d9287243b 100644 --- a/packages/components/nodes/vectorstores/MongoDB/MongoDB_Upsert.ts +++ b/packages/components/nodes/vectorstores/MongoDBAtlas/MongoDB_Upsert.ts @@ -10,7 +10,7 @@ import { MongoDBSearchBase } from './MongoDBSearchBase' class MongoDBUpsert_VectorStores extends MongoDBSearchBase implements INode { constructor() { super() - this.label = 'MongoDB Upsert Document' + this.label = 'MongoDB Atlas Upsert Document' this.name = 'MongoDBUpsert' this.version = 1.0 this.description = 'Upsert documents to MongoDB Atlas' diff --git a/packages/components/nodes/vectorstores/MongoDB/mongodb.png b/packages/components/nodes/vectorstores/MongoDBAtlas/mongodb.png similarity index 100% rename from packages/components/nodes/vectorstores/MongoDB/mongodb.png rename to packages/components/nodes/vectorstores/MongoDBAtlas/mongodb.png