MongoDB
MongoDB node reference - all 24 operations, the credential it needs, and a worked example.
Read and write a MongoDB database: find, count, distinct and aggregate; insert, update, replace, delete and bulk-write documents; claim a document atomically; manage indexes; and run raw database commands.
Credential: MongoDB connection string - see Credentials.
Privileges
Each operation below lists the privilege it needs. Privileges are granted by role-based access control to the MongoDB user in the connection string. MongoDB has no scopes and no consent screen - the equivalent question is which privilege action the connecting user holds on the collection, which is exactly what a not authorized on ... to execute command error is asking for. The built-in roles cover most of it: read for the reads, readWrite for the writes, dbAdmin to drop an index, and clusterMonitor or readAnyDatabase to list databases. If a run fails with a permission error, the node names the missing privilege in the error - grant it and re-run; you do not need to rebuild the workflow.
Operations (24)
Documents — read
| Operation | What it does | Privilege |
|---|---|---|
find | Find documents | find on the collection (role: read) |
findOne | Find one document | find on the collection (role: read) |
countDocuments | Count documents | find on the collection (role: read) |
estimatedDocumentCount | Estimate total count | find on the collection (role: read) |
distinct | Get distinct values | find on the collection (role: read) |
aggregate | Run an aggregation pipeline | find on the collection (role: read) — plus insert and update on the target when the pipeline ends in $out or $merge |
Documents — write
| Operation | What it does | Privilege |
|---|---|---|
insertOne | Insert a document | insert on the collection (role: readWrite) |
insertMany | Insert many documents | insert on the collection (role: readWrite) |
updateOne | Update one document | update and find on the collection (role: readWrite) |
updateMany | Update many documents | update and find on the collection (role: readWrite) |
replaceOne | Replace a document | update and find on the collection (role: readWrite) |
deleteOne | Delete one document | remove and find on the collection (role: readWrite) |
deleteMany | Delete many documents | remove and find on the collection (role: readWrite) |
bulkWrite | Bulk write (mixed operations) | whichever of insert, update and remove the operations use (role: readWrite) |
Documents — read and write atomically
| Operation | What it does | Privilege |
|---|---|---|
findOneAndUpdate | Find and update | update and find on the collection (role: readWrite) |
findOneAndReplace | Find and replace | update and find on the collection (role: readWrite) |
findOneAndDelete | Find and delete | remove and find on the collection (role: readWrite) |
Indexes
| Operation | What it does | Privilege |
|---|---|---|
listIndexes | List indexes | listIndexes on the collection (role: read) |
createIndex | Create an index | createIndex on the collection (role: readWrite or dbAdmin) |
dropIndex | Drop an index | dropIndex on the collection (role: dbAdmin) |
Database
| Operation | What it does | Privilege |
|---|---|---|
listCollections | List collections | listCollections on the database (role: read) |
listDatabases | List databases | listDatabases on the cluster (role: readAnyDatabase or clusterMonitor) |
runCommand | Run a database command | whatever the command itself needs — this is an escape hatch |
ping | Check the connection | none — ping is allowed before authentication |
Example
Claim the oldest queued job so two runs never take the same one
A workflow polls a jobs collection and processes one document at a time. Reading the oldest job and then updating it in two steps is a race: a second run can read the same document before the first marks it taken. findOneAndUpdate does the match, the write and the read as one server operation, so exactly one run gets each job.
Set Operation to findOneAndUpdate, then fill in:
| Field | Value | Notes |
|---|---|---|
database | shop | Omit to use the database in the connection string |
collection | jobs | The collection to claim from |
filter | {"status": "queued"} | Which documents are claimable; values are always values, never operators, even when they come from an expression |
sort | {"createdAt": 1} | Oldest first - without a sort, WHICH matching document you get is arbitrary |
update | {"$set": {"status": "running", "claimedAt": {"$date": "{{ now }}"}}} | A plain object here would be read as $set; the $date wrapper stores a real BSON date rather than a string |
returnDocument | after | Hand back the document as it is now, so the rest of the workflow sees status: running |
Sets {{job.row}} (the claimed document, with _id as a plain hex string) and {{job.found}} (false when the queue was empty - branch on it rather than assuming a document). To address that same document later, wrap the id in an $oid - a bare hex string will not match it, because MongoDB compares types strictly.