npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-mongoid

v1.0.36

Published

n8n node: MongoDB operations with field type mapping (ObjectId, Date, etc)

Downloads

111

Readme

n8n-nodes-mongoid

🧩 A custom node for n8n that allows inserting, updating, and finding MongoDB documents with full control over data types (ObjectId, Date, Number, etc).


🚀 What this node does

This node makes life easier for those working with MongoDB in n8n, allowing you to:

  • Insert documents into MongoDB
  • Update existing documents (with upsert support)
  • Find documents with custom filters
  • Map fields with specific types (ObjectId, Date, Number, String, Boolean, Array, Object)
  • Automatically convert values to the correct MongoDB types
  • Robust validation with clear error messages
  • Expression support for all fields

📦 Installation

Via npm

npm install n8n-nodes-mongoid

Via yarn

yarn add n8n-nodes-mongoid

After installation, restart n8n so the node appears in the available nodes list as "Mongo Extended".


🔧 Configuration

1. MongoDB Credentials

Configure MongoDB credentials securely. You can choose between two methods:

🔒 Recommended Method: Separate Fields (More Secure)

Use this method for better security. Credentials are stored separately and encrypted by n8n.

Configuration:

  1. Connection Type: Select Separate Fields
  2. Host: MongoDB server address (e.g., cluster1-pri.fzicr.mongodb.net)
  3. Port: MongoDB port (default: 27017, leave empty for MongoDB Atlas)
  4. User: MongoDB username
  5. Password: Password (encrypted field) 🔐
  6. Use SSL/TLS: Enabled (recommended)
  7. Use SRV: Enabled for MongoDB Atlas
  8. Additional Options: Extra parameters (e.g., retryWrites=true&w=majority)
  9. Database: Database name

Advantages:

  • ✅ Password is stored in encrypted field
  • ✅ Does not expose credentials in plain text
  • ✅ Easier to audit and manage
  • ✅ Follows security best practices

⚠️ Alternative Method: Full Connection String

Use only for compatibility or special cases.

Configuration:

  1. Connection Type: Select Full Connection String
  2. Connection String: Complete URL (e.g., mongodb+srv://user:[email protected])
  3. Database: Database name

Disadvantages:

  • ⚠️ Username and password are visible in the connection string
  • ⚠️ Less secure
  • ⚠️ Makes credential auditing difficult

2. Available Operations

🔹 Operation: Insert

Inserts a new document into the specified collection.

Settings:

  • Collection: MongoDB collection name
  • Field Mapping: Configure each document field:
    • Field Name in MongoDB: Name the field will have in the document (e.g., userId, email)
    • Data Type: Select the type (String, Number, Boolean, ObjectId, Date, Array, Object)
    • Value Source: Path to field in input JSON, literal value, or n8n expression

Example:

If the input item is:

{
  "userId": "507f1f77bcf86cd799439011",
  "email": "[email protected]",
  "age": "25"
}

Configure the mapping:

  • Field: _id | Type: ObjectId | Source: json.userId
  • Field: email | Type: String | Source: json.email
  • Field: age | Type: Number | Source: json.age

Result in MongoDB:

{
  "_id": ObjectId("507f1f77bcf86cd799439011"),
  "email": "[email protected]",
  "age": 25
}

🔹 Operation: Update

Updates an existing document in the collection.

Additional settings:

  • Update Filter: Field used to find the document (e.g., _id, email)
  • Filter Value: Path in input JSON, literal value, or expression
  • Filter Type: Filter data type (String, ObjectId, Number)
  • Upsert: If enabled, inserts the document if it doesn't exist

Update Example:

Input item:

{
  "id": "507f1f77bcf86cd799439011",
  "name": "John Silva",
  "updatedAt": "2025-01-15T10:30:00Z"
}

Settings:

  • Filter: _id
  • Filter Value: json.id (or literal value: 507f1f77bcf86cd799439011)
  • Filter Type: ObjectId
  • Upsert: true

Mapping:

  • Field: name | Type: String | Source: json.name
  • Field: updatedAt | Type: Date | Source: json.updatedAt

🔹 Operation: Find

Searches for documents in the collection with custom filters.

Settings:

  • Search Filter: Add multiple filters
    • Field Name: MongoDB field to filter
    • Field Type: Data type (String, Number, Boolean, ObjectId, Date)
    • Value: Path in JSON, literal value, or expression
  • Sort: Add fields to sort the results
    • Field Name: Field to sort by (e.g., createdAt, name, age)
    • Order: Ascending (1) or Descending (-1)
  • Result Limit: Maximum number of documents (0 = no limit)
  • Skip: Number of documents to skip (pagination)

Example 1: Find active users sorted by creation date

Find active users and return the 10 most recent:

Filters:

  • Field: status | Type: String | Value: active

Sort:

  • Field: createdAt | Order: Descending (Z-A, 9-1, most recent)

Limit: 10 Skip: 0

Result: Returns the 10 most recent active users (sorted by creation date, newest to oldest).


Example 2: Find products sorted by price and name

Find all in-stock products, sorted first by price (lowest to highest) and then by name (A-Z):

Filters:

  • Field: inStock | Type: Boolean | Value: true

Sort:

  • Field: price | Order: Ascending (A-Z, 1-9, oldest)
  • Field: name | Order: Ascending (A-Z, 1-9, oldest)

Limit: 50

Result: In-stock products sorted by price (cheapest to most expensive), and in case of equal prices, sorted alphabetically by name.


Example 3: Pagination with sorting

Find the second page of posts (10 items per page) sorted by publication date:

Filters: (none - find all)

Sort:

  • Field: publishedAt | Order: Descending (Z-A, 9-1, most recent)

Limit: 10 Skip: 10 ⬅️ Skip the first 10 (first page)

Result: Posts 11-20 most recent.


🛠️ Supported Data Types

📝 String

Converts any value to text.

Examples:

// Literal value
"John Silva"

// JSON path
json.name

// Expression
{{ $json.firstName + ' ' + $json.lastName }}

🔢 Number

Converts values to number. Validates if the result is a valid number.

Examples:

// Literal value
25
3.14

// String that will be converted
"42"

// JSON path
json.age

// Expression
{{ $json.quantity * $json.price }}

Error if invalid:

Invalid value for Number for field "age": "abc". Expected a valid number.

✅ Boolean

Converts values to boolean.

Accepted values:

  • Booleans: true, false
  • Strings: "true", "false", "1", "0" (case insensitive)
  • Numbers: 1 (true), 0 (false), any number other than 0 (true)

Examples:

// Literal value
true
false

// String
"true"
"false"
"1"
"0"

// JSON path
json.isActive

// Expression
{{ $json.age >= 18 }}
{{ true }}

Error if invalid:

Invalid value for Boolean for field "active": "yes". Expected true, false, 1, 0, or expression.

🆔 ObjectId

Converts a 24-character hexadecimal string to MongoDB ObjectId.

Expected format: Hexadecimal string with exactly 24 characters (0-9, a-f, A-F)

Examples:

// Literal value
507f1f77bcf86cd799439011

// JSON path
json.userId

// Expression (not recommended, use direct value)
{{ $json.id }}

Error if invalid:

Invalid value for ObjectId for field "_id": "123". Expected a 24-character hexadecimal string.

📅 Date

Converts values to MongoDB Date. Accepts various formats.

Accepted formats:

  • ISO 8601: 2025-01-15T10:30:00Z, 2025-01-15T10:30:00.000Z
  • Simple date: 2025-01-15, 2025/01/15
  • Numeric timestamp: 1705318200000
  • JavaScript Date object: new Date()

Examples:

// Literal value (ISO 8601)
2025-01-15T10:30:00Z
2025-01-15

// Timestamp
1705318200000

// JSON path
json.createdAt

// Expression - Current date
{{ new Date() }}

// Expression - Specific date
{{ new Date('2025-01-01') }}

// Expression - Add days
{{ new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) }}

Error if invalid:

Invalid value for Date for field "createdAt": "invalid". Expected ISO 8601 format (e.g., 2024-01-01T12:00:00Z, 2024-01-01, or timestamp).

📋 Array (auto-converts ObjectIds)

Converts values to array. 24-character hexadecimal strings are automatically converted to ObjectId.

Supports arrays of any type: strings, numbers, objects, dates, etc.

Basic examples:

// Literal JSON value (must be valid)
["item1", "item2", "item3"]
[1, 2, 3]

// JSON path (if already array)
json.tags

// Expression - Direct array
{{ ["tag1", "tag2"] }}

// Expression - Split string
{{ $json.categories.split(',') }}

// Single value (will be converted to array)
"single-value"
// Result: ["single-value"]

Arrays of objects:

// Expression - Array of objects
{{ [
  { id: 1, name: "Item 1", active: true },
  { id: 2, name: "Item 2", active: false }
] }}

// Array of complex objects with dates and ObjectIds
{{ [
  {
    userId: "507f1f77bcf86cd799439011",
    role: "admin",
    createdAt: new Date(),
    permissions: ["read", "write", "delete"]
  },
  {
    userId: "507f1f77bcf86cd799439012",
    role: "user",
    createdAt: new Date(),
    permissions: ["read"]
  }
] }}

// Transform JSON data into array of objects
{{ $json.users.map(u => ({
  name: u.fullName,
  email: u.email,
  active: u.status === 'active'
})) }}

Practical examples:

// Article tags
json.tags
// If json.tags = ["javascript", "nodejs"]
// Result: ["javascript", "nodejs"]

// Categories from comma-separated string
{{ $json.categories.split(',').map(c => c.trim()) }}
// If categories = "tech, programming, tutorial"
// Result: ["tech", "programming", "tutorial"]

// Array of products with calculated prices
{{ $json.items.map(item => ({
  productId: item.id,
  quantity: item.qty,
  totalPrice: item.qty * item.price,
  addedAt: new Date()
})) }}

📋 Array (without ObjectId conversion)

New! Use this type when you DON'T want 24-character strings to be converted to ObjectId.

When to use: When you have IDs that look like ObjectIds but should remain as strings (e.g., external IDs, codes, references).

Examples:

// Array with IDs that should remain strings
{{ [
  { externalId: "507f1f77bcf86cd799439011", provider: "stripe" },
  { externalId: "507f1f77bcf86cd799439012", provider: "paypal" }
] }}

// Result in MongoDB (externalId stays as STRING):
[
  { externalId: "507f1f77bcf86cd799439011", provider: "stripe" },
  { externalId: "507f1f77bcf86cd799439012", provider: "paypal" }
]

// If you used "Array (auto-converts ObjectIds)", the result would be:
[
  { externalId: ObjectId("507f1f77bcf86cd799439011"), provider: "stripe" }, // ❌ Converted!
  { externalId: ObjectId("507f1f77bcf86cd799439012"), provider: "paypal" }
]

🔗 Array of ObjectIds

Special type for arrays containing only MongoDB ObjectIds. Validates that all elements are valid ObjectIds.

Examples:

// Array of IDs as strings (will be converted to ObjectId)
["507f1f77bcf86cd799439011", "507f1f77bcf86cd799439012", "507f1f77bcf86cd799439013"]

// JSON path
json.userIds
// If userIds = ["507f1f77bcf86cd799439011", "507f1f77bcf86cd799439012"]
// Result: [ObjectId("507f1f77bcf86cd799439011"), ObjectId("507f1f77bcf86cd799439012")]

// Expression
{{ $json.collaborators.map(c => c.userId) }}
// If collaborators = [{ userId: "507f1f77bcf86cd799439011" }, { userId: "507f1f77bcf86cd799439012" }]
// Result: [ObjectId("507f1f77bcf86cd799439011"), ObjectId("507f1f77bcf86cd799439012")]

Error if invalid:

Invalid value in ObjectId array for field "members": "123". Expected 24-character hexadecimal string.

📦 Object (auto-converts ObjectIds)

Converts values to JSON object. 24-character hexadecimal strings within the object are automatically converted to ObjectId.

If already an object, keeps it; if a string, tries to parse as JSON.

Examples:

// Literal JSON value
{"name": "John", "age": 30}
{"address": {"city": "São Paulo", "country": "Brazil"}}

// JSON path (if already object)
json.metadata
json.config

// Expression - Direct object
{{ { name: $json.firstName, age: $json.age } }}

// Expression - Build object
{{ {
  user: $json.username,
  timestamp: new Date(),
  data: $json.rawData
} }}

// Valid JSON string (will be parsed)
'{"key": "value"}'

Practical examples:

// User metadata
json.metadata
// If metadata = { "plan": "premium", "verified": true }
// Result: { "plan": "premium", "verified": true }

// Embedded configuration
{{ { theme: "dark", language: $json.lang, notifications: true } }}
// Result: { "theme": "dark", "language": "en-US", "notifications": true }

// Full address
{{ {
  street: $json.street,
  city: $json.city,
  zipCode: $json.zip,
  coordinates: { lat: $json.lat, lng: $json.lng }
} }}

Error if invalid:

Invalid value for Object for field "config": "invalid json". Expected a valid JSON object.

📦 Object (without ObjectId conversion)

New! Use this type when you DON'T want 24-character strings within the object to be converted to ObjectId.

When to use: When you have external IDs, tracking codes, or any string that looks like ObjectId but should remain as string.

Examples:

// Object with external IDs that should remain strings
{{ {
  userId: $json.userId,
  stripeCustomerId: "507f1f77bcf86cd799439011",
  paypalCustomerId: "507f1f77bcf86cd799439012",
  metadata: {
    trackingCode: "507f1f77bcf86cd799439013"
  }
} }}

// Result in MongoDB (IDs remain as STRINGS):
{
  userId: ObjectId("..."),  // userId from $json can be ObjectId if it already is
  stripeCustomerId: "507f1f77bcf86cd799439011",  // ✅ String
  paypalCustomerId: "507f1f77bcf86cd799439012",  // ✅ String
  metadata: {
    trackingCode: "507f1f77bcf86cd799439013"  // ✅ String
  }
}

// If you used "Object (auto-converts ObjectIds)":
{
  userId: ObjectId("..."),
  stripeCustomerId: ObjectId("507f1f77bcf86cd799439011"),  // ❌ Converted!
  paypalCustomerId: ObjectId("507f1f77bcf86cd799439012"),  // ❌ Converted!
  metadata: {
    trackingCode: ObjectId("507f1f77bcf86cd799439013")  // ❌ Converted!
  }
}

Use cases:

  • External system IDs (Stripe, PayPal, etc.)
  • Tracking codes
  • External references
  • Any identifier that is not from MongoDB

🔄 Update Operators for Arrays

The Update operation has 4 operators to manipulate arrays. See how to use each one step by step in the node.


📌 $set - Replace values (default)

What it does: Completely replaces the field value (overwrites everything).

When to use: When you want to replace the entire array or substitute a simple value.

🎯 Practical Example 1: Replace complete tag array

Scenario: You have a post with old tags and want to replace them with new tags.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "My Post",
  tags: ["old-tag1", "old-tag2"]
}

Node configuration:

  1. Operation: Update
  2. Collection: posts
  3. Update Filter: _id
  4. Filter Value: 507f1f77bcf86cd799439011
  5. Filter Type: ObjectId
  6. Update Operator: $set ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: tags
    • Data Type: Array
    • Value Source: {{ ["react", "typescript", "tutorial"] }}

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "My Post",
  tags: ["react", "typescript", "tutorial"] // ✅ Array replaced
}

📌 $push - Add item to array

What it does: Adds a new item to the end of the existing array (doesn't remove anything).

When to use: When you want to add comments, history, cart items, etc.

🎯 Practical Example 2: Add comment to a post

Scenario: User is adding a comment to a post.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "My Post",
  comments: [
    { userId: "507f...", text: "First comment", createdAt: ISODate("2025-01-10") }
  ]
}

Input item in n8n:

{
  "postId": "507f1f77bcf86cd799439011",
  "userId": "507f1f77bcf86cd799439012",
  "commentText": "Great post!"
}

Node configuration:

  1. Operation: Update
  2. Collection: posts
  3. Update Filter: _id
  4. Filter Value: json.postId
  5. Filter Type: ObjectId
  6. Update Operator: $push ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: comments
    • Data Type: Object
    • Value Source: {{ { userId: $json.userId, text: $json.commentText, createdAt: new Date() } }}

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "My Post",
  comments: [
    { userId: "507f...", text: "First comment", createdAt: ISODate("2025-01-10") },
    { userId: "507f1f77bcf86cd799439012", text: "Great post!", createdAt: ISODate("2025-01-15") } // ✅ New comment
  ]
}

🎯 Practical Example 3: Add collaborator to a project

Scenario: Add a new collaborator to the project.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  name: "Project ABC",
  collaborators: [
    ObjectId("507f1f77bcf86cd799439020")
  ]
}

Node configuration:

  1. Operation: Update
  2. Collection: projects
  3. Update Filter: _id
  4. Filter Value: 507f1f77bcf86cd799439011
  5. Filter Type: ObjectId
  6. Update Operator: $push ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: collaborators
    • Data Type: ObjectId
    • Value Source: 507f1f77bcf86cd799439021 (or json.newUserId)

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  name: "Project ABC",
  collaborators: [
    ObjectId("507f1f77bcf86cd799439020"),
    ObjectId("507f1f77bcf86cd799439021") // ✅ New collaborator
  ]
}

⚠️ WARNING: $push always adds, even if the item already exists (can duplicate). Use $addToSet to avoid duplicates.


📌 $addToSet - Add unique item (no duplicates)

What it does: Adds an item to the array only if it doesn't exist yet (doesn't duplicate).

When to use: Tags, categories, group members - anything that shouldn't have duplicates.

🎯 Practical Example 4: Add tag without duplicating

Scenario: User is adding the "javascript" tag to a post. If it already exists, don't add it again.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "Tutorial",
  tags: ["react", "frontend"]
}

Node configuration:

  1. Operation: Update
  2. Collection: posts
  3. Update Filter: _id
  4. Filter Value: 507f1f77bcf86cd799439011
  5. Filter Type: ObjectId
  6. Update Operator: $addToSet ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: tags
    • Data Type: String
    • Value Source: javascript

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "Tutorial",
  tags: ["react", "frontend", "javascript"] // ✅ Tag added
}

If run again with the same tag:

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "Tutorial",
  tags: ["react", "frontend", "javascript"] // ✅ No duplicate!
}

🎯 Practical Example 5: Add member to group (without duplicating)

Scenario: Add user to a group, but only if they're not already a member.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  groupName: "Admins",
  members: [
    ObjectId("507f1f77bcf86cd799439020")
  ]
}

Node configuration:

  1. Operation: Update
  2. Collection: groups
  3. Update Filter: _id
  4. Filter Value: 507f1f77bcf86cd799439011
  5. Filter Type: ObjectId
  6. Update Operator: $addToSet ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: members
    • Data Type: ObjectId
    • Value Source: 507f1f77bcf86cd799439021

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  groupName: "Admins",
  members: [
    ObjectId("507f1f77bcf86cd799439020"),
    ObjectId("507f1f77bcf86cd799439021") // ✅ Member added
  ]
}

📌 $pull - Remove item from array

What it does: Removes all items from the array that match the specified value.

When to use: Remove tags, delete comments, remove collaborators, etc.

🎯 Practical Example 6: Remove specific tag

Scenario: Remove the "deprecated" tag from a post.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "Old Post",
  tags: ["javascript", "deprecated", "tutorial", "deprecated"]
}

Node configuration:

  1. Operation: Update
  2. Collection: posts
  3. Update Filter: _id
  4. Filter Value: 507f1f77bcf86cd799439011
  5. Filter Type: ObjectId
  6. Update Operator: $pull ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: tags
    • Data Type: String
    • Value Source: deprecated

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  title: "Old Post",
  tags: ["javascript", "tutorial"] // ✅ All occurrences of "deprecated" removed
}

🎯 Practical Example 7: Remove collaborator from project

Scenario: Remove a user from the collaborators list.

Document in MongoDB (before):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  name: "Project ABC",
  collaborators: [
    ObjectId("507f1f77bcf86cd799439020"),
    ObjectId("507f1f77bcf86cd799439021"),
    ObjectId("507f1f77bcf86cd799439022")
  ]
}

Input item in n8n:

{
  "projectId": "507f1f77bcf86cd799439011",
  "userToRemove": "507f1f77bcf86cd799439021"
}

Node configuration:

  1. Operation: Update
  2. Collection: projects
  3. Update Filter: _id
  4. Filter Value: json.projectId
  5. Filter Type: ObjectId
  6. Update Operator: $pull ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: collaborators
    • Data Type: ObjectId
    • Value Source: json.userToRemove

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  name: "Project ABC",
  collaborators: [
    ObjectId("507f1f77bcf86cd799439020"),
    ObjectId("507f1f77bcf86cd799439022") // ✅ User 021 removed
  ]
}

📊 Operator Summary Table

| Operator | What it does | Duplicates? | Example Use | |----------|-------------|------------|-------------| | $set | Replaces complete value | N/A | Replace entire tag array | | $push | Adds to end of array | ✅ Yes | Add comment, history | | $addToSet | Adds if doesn't exist | ❌ No | Add tag, group member | | $pull | Removes matching items | N/A | Remove tag, collaborator |


🎯 Update Specific Field Inside Array (Positional Operator $)

Scenario: You have an array of objects and want to update only one field of a specific object within the array.

📌 Practical Example: Update resolution for a specific question

Document in MongoDB:

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  examId: "exam-123",
  questions: [
    {
      questionId: "q1",
      text: "What is the capital of Brazil?",
      resolution: null,
      points: 10
    },
    {
      questionId: "q2",
      text: "What is 2+2?",
      resolution: null,
      points: 5
    }
  ]
}

Goal: Update the resolution field of the question with questionId: "q1".

Input item in n8n:

{
  "examId": "exam-123",
  "questionId": "q1",
  "resolution": "The capital of Brazil is Brasília"
}

✅ Solution: Use array filter + positional operator $

Node configuration:

  1. Operation: Update
  2. Collection: exams
  3. Update Filter: questions.questionId ⬅️ Filter by field inside array
  4. Filter Value: json.questionId
  5. Filter Type: String
  6. Update Operator: $set ⬅️ IMPORTANT
  7. Field Mapping:
    • Field Name: questions.$.resolution ⬅️ Use $ to reference the found item
    • Data Type: String
    • Value Source: json.resolution

📝 Explanation of Positional Operator $

  • questions.questionId in filter → MongoDB searches inside the questions array for an object where questionId equals the provided value
  • questions.$.resolution in field → The $ represents the first element of the array that matched the filter
  • MongoDB updates only that specific object, not the entire array

Document in MongoDB (after):

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  examId: "exam-123",
  questions: [
    {
      questionId: "q1",
      text: "What is the capital of Brazil?",
      resolution: "The capital of Brazil is Brasília", // ✅ Updated!
      points: 10
    },
    {
      questionId: "q2",
      text: "What is 2+2?",
      resolution: null, // ⚪ Not modified
      points: 5
    }
  ]
}

🎯 Another Example: Update multiple fields of an array item

Scenario: Update resolution and answeredBy for a question.

Input item in n8n:

{
  "examId": "exam-123",
  "questionId": "q2",
  "resolution": "4",
  "answeredBy": "507f1f77bcf86cd799439020"
}

Node configuration:

  1. Operation: Update
  2. Collection: exams
  3. Update Filter: questions.questionId
  4. Filter Value: json.questionId
  5. Filter Type: String
  6. Update Operator: $set
  7. Field Mapping:
    • Field 1:
      • Field Name: questions.$.resolution
      • Data Type: String
      • Value Source: json.resolution
    • Field 2:
      • Field Name: questions.$.answeredBy
      • Data Type: ObjectId
      • Value Source: json.answeredBy

Result:

{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  examId: "exam-123",
  questions: [
    {
      questionId: "q1",
      text: "What is the capital of Brazil?",
      resolution: "The capital of Brazil is Brasília",
      points: 10
    },
    {
      questionId: "q2",
      text: "What is 2+2?",
      resolution: "4", // ✅ Updated!
      answeredBy: ObjectId("507f1f77bcf86cd799439020"), // ✅ Updated!
      points: 5
    }
  ]
}

⚠️ Limitations of Positional Operator $

  1. Updates only the first element that matches the filter
  2. Doesn't work with nested arrays (use $[] or $[<identifier>] for more complex cases)
  3. Requires a filter on the array - the $ needs a filter to know which element to update

💡 Tip: Compound Filters

You can combine filters on the main document + filter on the array:

Configuration:

  • Update Filter: examId
  • Filter Value: json.examId
  • Type: String

Then add a second filter using field configuration creatively, but the current node only supports one filter. For multiple filters, use the filter in the format:

examId AND questions.questionId

However, in the current node, you can filter directly by questions.questionId which will work.


💡 Use Cases

1. Insert user with automatic creation date

Mapping:

  • Field: name | Type: String | Source: json.name
  • Field: email | Type: String | Source: json.email
  • Field: createdAt | Type: Date | Source: {{ new Date() }}
  • Field: isActive | Type: Boolean | Source: true

2. Convert IDs from string to ObjectId

When receiving data from external APIs, IDs usually come as strings. This node automatically converts them to ObjectId.

Mapping:

  • Field: userId | Type: ObjectId | Source: json.userId
  • Field: institutionId | Type: ObjectId | Source: 68e466346a2c77b2cb0cc805

3. Save array of tags

Mapping:

  • Field: title | Type: String | Source: json.title
  • Field: tags | Type: Array | Source: {{ $json.categories.split(',') }}
  • Field: metadata | Type: Object | Source: {{ { views: 0, likes: 0 } }}

4. Update document with upsert

Use Update with upsert enabled to update if exists or create if doesn't exist:

Filter:

  • Field: _id
  • Type: ObjectId
  • Value: json.id
  • Upsert:

5. Find documents with multiple filters

Filters:

  • Field: status | Type: String | Value: active
  • Field: role | Type: String | Value: admin
  • Field: createdAt | Type: Date | Value: {{ new Date('2025-01-01') }}

Limit: 50


6. Add comment to a document

Adds a new comment to a post's comments array.

Operation: Update Filter: _id | Type: ObjectId | Value: json.postId Operator: $push

Mapping:

  • Field: comments | Type: Object | Source: {{ { userId: $json.userId, text: $json.comment, createdAt: new Date() } }}

Result:

// Before
{ _id: ObjectId("..."), comments: [] }

// After
{
  _id: ObjectId("..."),
  comments: [
    { userId: "507f...", text: "Great post!", createdAt: ISODate("2025-01-15...") }
  ]
}

7. Add collaborator to project (without duplicating)

Adds a user to the collaborators array only if they're not already there.

Operation: Update Filter: _id | Type: ObjectId | Value: json.projectId Operator: $addToSet

Mapping:

  • Field: collaborators | Type: ObjectId | Source: json.userId

8. Remove collaborator from project

Removes a specific user from the collaborators array.

Operation: Update Filter: _id | Type: ObjectId | Value: json.projectId Operator: $pull

Mapping:

  • Field: collaborators | Type: ObjectId | Source: json.userIdToRemove

9. Save status history

Adds status change record to the document's history.

Operation: Update Filter: _id | Type: ObjectId | Value: json.orderId Operator: $push

Mapping:

  • Field: statusHistory | Type: Object | Source: {{ { status: $json.newStatus, changedBy: $json.userId, changedAt: new Date(), notes: $json.notes } }}

Result:

{
  _id: ObjectId("..."),
  statusHistory: [
    { status: "pending", changedBy: "user1", changedAt: ISODate("..."), notes: "Order created" },
    { status: "processing", changedBy: "user2", changedAt: ISODate("..."), notes: "Started processing" },
    { status: "completed", changedBy: "user2", changedAt: ISODate("..."), notes: "Order completed" }
  ]
}

10. Manage product array in cart

Insert cart with products:

Operation: Insert

Mapping:

  • Field: userId | Type: ObjectId | Source: json.userId
  • Field: items | Type: Array | Source: {{ $json.products.map(p => ({ productId: p.id, quantity: p.qty, price: p.price, addedAt: new Date() })) }}
  • Field: createdAt | Type: Date | Source: {{ new Date() }}

Add product to existing cart:

Operation: Update Filter: userId | Type: ObjectId | Value: json.userId Operator: $push

Mapping:

  • Field: items | Type: Object | Source: {{ { productId: $json.productId, quantity: $json.quantity, price: $json.price, addedAt: new Date() } }}

📝 Important Tips

✅ Literal Values vs JSON Paths vs Expressions

Literal Value:

507f1f77bcf86cd799439011
true
2025-01-15

JSON Path:

json.userId
json.data.email
json.metadata.createdAt

n8n Expression:

{{ new Date() }}
{{ $json.age >= 18 }}
{{ $json.firstName + ' ' + $json.lastName }}

The node automatically detects which type you're using!


✅ Error Validation

All validations return clear messages indicating:

  • Which field had an error
  • Which value was provided
  • Which format is expected
  • Examples of valid values

✅ Null Values

Fields with null or undefined are ignored and don't appear in the final MongoDB document.


🐛 Troubleshooting

Error: "path.split is not a function"

This occurred in old versions when using expressions like {{ new Date() }}. Current version resolves automatically.

Error: "Invalid value for ObjectId"

Make sure the ObjectId has exactly 24 hexadecimal characters (0-9, a-f).

Error: "Invalid value for Date"

Use ISO 8601 formats (2025-01-15T10:30:00Z) or expressions ({{ new Date() }}).

Update doesn't find document

Verify that:

  • The filter is correct
  • The filter type matches the field type in MongoDB
  • The filter value exists in the input item

📄 License

MIT


🤝 Contributing

Contributions are welcome! Open an issue or pull request in the repository.