diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/VectorStoreMongoDBAtlas.node.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/VectorStoreMongoDBAtlas.node.ts
new file mode 100644
index 0000000000..6c3efa96cf
--- /dev/null
+++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/VectorStoreMongoDBAtlas.node.ts
@@ -0,0 +1,180 @@
+import { MongoDBAtlasVectorSearch } from '@langchain/mongodb';
+import { MongoClient } from 'mongodb';
+import { NodeOperationError, type INodeProperties } from 'n8n-workflow';
+
+import { metadataFilterField } from '@utils/sharedFields';
+import {
+ mongoCollectionRLC,
+ embeddingField,
+ metadataField,
+ vectorIndexName,
+} from '../shared/descriptions';
+import { mongoCollectionSearch } from '../shared/methods/listSearch';
+
+import { createVectorStoreNode } from '../shared/createVectorStoreNode';
+
+const sharedFields: INodeProperties[] = [
+ mongoCollectionRLC,
+ embeddingField,
+ metadataField,
+ vectorIndexName,
+];
+
+const mongoNamespaceField: INodeProperties = {
+ displayName: 'Namespace',
+ name: 'namespace',
+ type: 'string',
+ description: 'Logical partition for documents. Uses metadata.namespace field for filtering.',
+ default: '',
+};
+
+const retrieveFields: INodeProperties[] = [
+ {
+ displayName: 'Options',
+ name: 'options',
+ type: 'collection',
+ placeholder: 'Add Option',
+ default: {},
+ options: [mongoNamespaceField, metadataFilterField],
+ },
+];
+
+const insertFields: INodeProperties[] = [
+ {
+ displayName: 'Options',
+ name: 'options',
+ type: 'collection',
+ placeholder: 'Add Option',
+ default: {},
+ options: [
+ {
+ displayName: 'Clear Namespace',
+ name: 'clearNamespace',
+ type: 'boolean',
+ default: false,
+ description: 'Whether to clear documents in the namespace before inserting new data',
+ },
+ mongoNamespaceField,
+ ],
+ },
+];
+
+export class VectorStoreMongoDBAtlas extends createVectorStoreNode({
+ meta: {
+ displayName: 'MongoDB Atlas Vector Store',
+ name: 'vectorStoreMongoDBAtlas',
+ description: 'Work with your data in MongoDB Atlas Vector Store',
+ icon: { light: 'file:mongodb.svg', dark: 'file:mongodb.dark.svg' },
+ docsUrl:
+ 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoremongodbatlas/',
+ credentials: [
+ {
+ name: 'mongoDb',
+ required: true,
+ },
+ ],
+ operationModes: ['load', 'insert', 'retrieve', 'update', 'retrieve-as-tool'],
+ },
+ methods: { listSearch: { mongoCollectionSearch } },
+ retrieveFields,
+ loadFields: retrieveFields,
+ insertFields,
+ sharedFields,
+ async getVectorStoreClient(context, filter, embeddings, itemIndex) {
+ try {
+ const collectionName = context.getNodeParameter('mongoCollection', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const vectorIndexName = context.getNodeParameter('vectorIndexName', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const embeddingField = context.getNodeParameter('embedding', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const metadataField = context.getNodeParameter('metadata_field', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const credentials = await context.getCredentials('mongoDb');
+ const client = new MongoClient(credentials.connectionString as string, {
+ appName: 'devrel.content.n8n_vector_integ', // Added appName
+ });
+ await client.connect();
+ const collection = client.db(credentials.database as string).collection(collectionName);
+
+ // test index exists
+ const indexes = await collection.listSearchIndexes().toArray();
+
+ const indexExists = indexes.some((index) => index.name === vectorIndexName);
+
+ if (!indexExists) {
+ throw new NodeOperationError(context.getNode(), `Index ${vectorIndexName} not found`, {
+ itemIndex,
+ description: 'Please check that the index exists in your collection',
+ });
+ }
+
+ return new MongoDBAtlasVectorSearch(embeddings, {
+ collection,
+ indexName: vectorIndexName, // Default index name
+ textKey: metadataField, // Field containing raw text
+ embeddingKey: embeddingField, // Field containing embeddings
+ });
+ } catch (error) {
+ throw new NodeOperationError(context.getNode(), `Error: ${error.message}`, {
+ itemIndex,
+ description: 'Please check your MongoDB Atlas connection details',
+ });
+ }
+ },
+ async populateVectorStore(context, embeddings, documents, itemIndex) {
+ try {
+ const collectionName = context.getNodeParameter('mongoCollection', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+ const embeddingField = context.getNodeParameter('embedding', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const metadataField = context.getNodeParameter('metadata_field', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const vectorIndexName = context.getNodeParameter('vectorIndexName', itemIndex, '', {
+ extractValue: true,
+ }) as string;
+
+ const credentials = await context.getCredentials('mongoDb');
+
+ const client = new MongoClient(credentials.connectionString as string, {
+ appName: 'devrel.content.n8n_vector_integ', // Added appName
+ });
+ await client.connect();
+
+ const db = client.db(credentials.database as string);
+
+ // Check if collection exists
+ const collections = await db.listCollections({ name: collectionName }).toArray();
+ if (collections.length === 0) {
+ await db.createCollection(collectionName);
+ }
+ const collection = db.collection(collectionName);
+ await MongoDBAtlasVectorSearch.fromDocuments(documents, embeddings, {
+ collection,
+ indexName: vectorIndexName, // Default index name
+ textKey: metadataField, // Field containing raw text
+ embeddingKey: embeddingField, // Field containing embeddings
+ });
+
+ await client.close();
+ } catch (error) {
+ throw new NodeOperationError(context.getNode(), `Error: ${error.message}`, {
+ itemIndex,
+ description: 'Please check your MongoDB Atlas connection details',
+ });
+ }
+ },
+}) {}
diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.dark.svg b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.dark.svg
new file mode 100644
index 0000000000..3ccdc84421
--- /dev/null
+++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.dark.svg
@@ -0,0 +1,3 @@
+
diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.svg b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.svg
new file mode 100644
index 0000000000..8da45829e2
--- /dev/null
+++ b/packages/@n8n/nodes-langchain/nodes/vector_store/VectorStoreMongoDBAtlas/mongodb.svg
@@ -0,0 +1,3 @@
+
diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/descriptions.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/descriptions.ts
index 483e73c1fe..c86c2df655 100644
--- a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/descriptions.ts
+++ b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/descriptions.ts
@@ -68,3 +68,54 @@ export const qdrantCollectionRLC: INodeProperties = {
},
],
};
+
+export const mongoCollectionRLC: INodeProperties = {
+ displayName: 'MongoDB Collection',
+ name: 'mongoCollection',
+ type: 'resourceLocator',
+ default: { mode: 'list', value: '' },
+ required: true,
+ modes: [
+ {
+ displayName: 'From List',
+ name: 'list',
+ type: 'list',
+ typeOptions: {
+ searchListMethod: 'mongoCollectionSearch', // Method to fetch collections
+ },
+ },
+ {
+ displayName: 'Name',
+ name: 'name',
+ type: 'string',
+ placeholder: 'e.g. my_collection',
+ },
+ ],
+};
+
+export const vectorIndexName: INodeProperties = {
+ displayName: 'Vector Index Name',
+ name: 'vectorIndexName',
+ type: 'string',
+ default: 'vector_index',
+ description: 'The name of the vector index',
+ required: true,
+};
+
+export const embeddingField: INodeProperties = {
+ displayName: 'Embedding',
+ name: 'embedding',
+ type: 'string',
+ default: 'embedding',
+ description: 'The field with the embedding array',
+ required: true,
+};
+
+export const metadataField: INodeProperties = {
+ displayName: 'Metadata Field',
+ name: 'metadata_field',
+ type: 'string',
+ default: 'text',
+ description: 'The text field of the raw data',
+ required: true,
+};
diff --git a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts
index 278d879f90..4616205845 100644
--- a/packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts
+++ b/packages/@n8n/nodes-langchain/nodes/vector_store/shared/methods/listSearch.ts
@@ -1,6 +1,7 @@
import { Pinecone } from '@pinecone-database/pinecone';
import { QdrantClient } from '@qdrant/js-client-rest';
import { ApplicationError, type IDataObject, type ILoadOptionsFunctions } from 'n8n-workflow';
+import { MongoClient } from 'mongodb';
export async function pineconeIndexSearch(this: ILoadOptionsFunctions) {
const credentials = await this.getCredentials('pineconeApi');
@@ -67,3 +68,25 @@ export async function qdrantCollectionsSearch(this: ILoadOptionsFunctions) {
return { results };
}
+
+export async function mongoCollectionSearch(this: ILoadOptionsFunctions) {
+ const credentials = await this.getCredentials('mongoDb');
+
+ const client = new MongoClient(credentials.connectionString as string, {
+ appName: 'devrel.content.n8n_vector_integ',
+ });
+ await client.connect();
+
+ try {
+ const db = client.db(credentials.database as string);
+ const collections = await db.listCollections().toArray();
+ const results = collections.map((collection) => ({
+ name: collection.name,
+ value: collection.name,
+ }));
+
+ return { results };
+ } finally {
+ await client.close();
+ }
+}
diff --git a/packages/@n8n/nodes-langchain/package.json b/packages/@n8n/nodes-langchain/package.json
index ffdd31a7b9..8e1d3b2c3f 100644
--- a/packages/@n8n/nodes-langchain/package.json
+++ b/packages/@n8n/nodes-langchain/package.json
@@ -150,6 +150,7 @@
"@langchain/google-vertexai": "0.1.8",
"@langchain/groq": "0.1.3",
"@langchain/mistralai": "0.2.0",
+ "@langchain/mongodb": "^0.1.0",
"@langchain/ollama": "0.1.4",
"@langchain/openai": "0.3.17",
"@langchain/pinecone": "0.1.3",