MongoDB component
The
mongodbcomponent inserts, queries, updates and deletes documents in MongoDB, and consumes change streams and tailable cursors.
Scheme: mongodb: · Crate: cameleer-datastores · Cargo feature: datastores · Consumer: yes · Producer: yes ·
Apache Camel: MongoDB
When to use it
- Store JSON documents from HTTP, Kafka or files without defining a schema first.
- Give an AI agent a memory: save notes, tool results or conversation turns per session and read the latest ones back before the next model call.
- React to changes: a change stream consumer routes every insert, update and delete.
- Run aggregations and bulk writes from a route.
URI format
mongodb:<connectionBean>?database=<db>&collection=<coll>&operation=<op>[&options]The connection is one of:
connectionUriString=mongodb://host:27017(ormongodb+srv://cluster.example.com, resolved with Cameleer's own DNS client), the path is then just a name;hosts=host1:27017,host2:27017withusername,passwordandauthSource;- a
MongoClientbound in the registry under the path name.
Put credentials in username and password rather than in connectionUriString: a
connection string with its own ? options does not fit inside the endpoint URI.
Bodies are documents: maps, JSON text (Extended JSON and shell syntax such as
ObjectId("...") are accepted) or lists of them. Results use Extended JSON for BSON-only types
({"$oid": "..."}, {"$date": "..."}).
Example
POST /notes stores the JSON body as a document and returns it with its generated _id. An
agent can call this as a "remember" tool.
- route:
id: save-note
from:
uri: "platform-http:/notes?httpMethodRestrict=POST"
steps:
- unmarshal:
json: {}
- to: "mongodb:agentDb?connectionUriString={{env:MONGODB_URI:mongodb://localhost:27017}}&database=agent&collection=notes&operation=insert"
- marshal:
json: {}GET /notes?session=s1 returns the 20 newest notes of one session. The query document comes
from the body; sort and limit come from headers.
- route:
id: recent-notes
from:
uri: "platform-http:/notes?httpMethodRestrict=GET"
steps:
- filter:
simple: "${header.session} !regex '^[A-Za-z0-9_-]+$'"
steps:
- setHeader:
name: CamelHttpResponseCode
constant: 400
- setBody:
constant: "invalid session"
- stop: {}
- setBody:
simple: '{"session": "${header.session}"}'
- setHeader:
name: CamelMongoDbSortBy
constant: '{"_id": -1}'
- setHeader:
name: CamelMongoDbLimit
constant: 20
- to: "mongodb:agentDb?connectionUriString={{env:MONGODB_URI:mongodb://localhost:27017}}&database=agent&collection=notes&operation=findAll"
- marshal:
json: {}The filter rejects session ids that are not plain words, so a request cannot inject query operators into the JSON.
Rust DSL
ctx.add_routes(|b| {
b.from("direct:remember")
.to("mongodb:agentDb?connectionUriString=mongodb://localhost:27017&database=agent&collection=notes&operation=insert");
b.from("mongodb:agentDb?connectionUriString=mongodb://localhost:27017&database=agent&collection=notes&consumerType=changeStreams")
.log("${header.CamelMongoDbStreamOperationType}: ${body}");
})?;Operations
| operation | body | result |
|---|---|---|
findById | the id | the document or null |
findOneByQuery | query document | the first match or null |
findAll | query document (null = all) | list of documents; headers CamelMongoDbResultTotalSize, CamelMongoDbResultPageSize |
findDistinct | query document | distinct values of the field in CamelMongoDbDistinctQueryField |
count | query document | the number of matches |
insert | document or list | the inserted document(s) with _id; header CamelMongoOid |
save | document with _id | replaces or inserts it |
update | [filter, update] list, or the update with the filter in CamelMongoDbCriteria | CamelMongoDbRecordsAffected, CamelMongoDbRecordsMatched; CamelMongoDbMultiUpdate, CamelMongoDbUpsert |
remove | query document | {deletedCount}; header CamelMongoDbRecordsAffected |
bulkWrite | list of insertOne, updateOne, updateMany, replaceOne, deleteOne, deleteMany models | counts; ordered unless CamelMongoDbBulkOrdered=false; write errors raise MongoBulkWriteException |
aggregate | pipeline (list of stages) | list of documents; CamelMongoDbAllowDiskUse |
getDbStats, getColStats | the stats document | |
command | command document | the reply |
Options
| option | default | description |
|---|---|---|
connectionUriString | mongodb:// or mongodb+srv:// connection string | |
hosts | host:port list, used with username, password, authSource | |
database | database name | |
collection | collection name | |
operation | producer operation (header CamelMongoDbOperation overrides it) | |
createCollection | true | create the collection on first use |
dynamicity | false | allow CamelMongoDbDatabase and CamelMongoDbCollection headers to pick the target |
writeResultAsHeader | false | put write results in CamelMongoWriteResult and keep the body |
consumerType | changeStreams or tailable | |
streamFilter | change streams: a $match document, for example {"operationType":"insert"} | |
fullDocument | change streams: updateLookup to receive the whole document on updates | |
tailTrackIncreasingField | tailable: the increasing field to resume from | |
cursorRegenerationDelay | 1000 ms | tailable: wait before reopening a dead cursor |
sslContextParameters | TLS trust (with tls=true in the connection string) |
Authentication supports SCRAM-SHA-256, SCRAM-SHA-1 and MONGODB-X509. Replica sets are
discovered with hello and followed after a primary change. readPreference, writeConcern,
collectionIndex, outputType and the persistent tail-tracking options are accepted and
ignored; tail tracking is kept in memory only.
Message headers
| header | direction | description |
|---|---|---|
CamelMongoDbOperation | in | operation for this exchange |
CamelMongoDbCriteria | in | query document (instead of the body) |
CamelMongoDbFieldsProjection | in | projection document |
CamelMongoDbSortBy | in | sort document |
CamelMongoDbLimit, CamelMongoDbNumToSkip, CamelMongoDbBatchSize | in | paging |
CamelMongoDbMultiUpdate, CamelMongoDbUpsert | in | update flags |
CamelMongoDbDistinctQueryField | in | field for findDistinct |
CamelMongoDbAllowDiskUse | in | aggregation flag |
CamelMongoDbBulkOrdered | in | false for unordered bulk writes |
CamelMongoDbDatabase, CamelMongoDbCollection | in | target, with dynamicity=true |
CamelMongoOid | out | id(s) of inserted documents |
CamelMongoDbRecordsAffected, CamelMongoDbRecordsMatched | out | write counts |
CamelMongoDbResultTotalSize, CamelMongoDbResultPageSize | out | query counts |
CamelMongoWriteResult | out | write result with writeResultAsHeader=true |
CamelMongoDbStreamOperationType | out | change streams: insert, update, delete, ... |
_id | out | change streams: the document key |
Run it with Docker
docker run --rm -p 8080:8080 -e MONGODB_URI=mongodb://mongo.example.com:27017 \
-v "$PWD:/routes:ro" pmsudhi/cameleer run /routes/notes.camel.yamlCommon questions
How do I connect with a username and password?
Use hosts=mongo.example.com:27017&username=app&password={{env:MONGODB_PASSWORD}}&authSource=admin
instead of putting them in connectionUriString.
How do I sort and limit a query?
Set the headers CamelMongoDbSortBy (for example {"_id": -1}) and CamelMongoDbLimit before a
findAll.
How do I react to new documents?
Consume with consumerType=changeStreams; add streamFilter={"operationType":"insert"} to see
inserts only. Change streams need a replica set on the server.
Does it work with Azure Cosmos DB or FerretDB?
It speaks the MongoDB wire protocol (OP_MSG) and was verified against FerretDB 1.24 and an
embedded server. Other compatible servers are not tested.
Related
- mongodb-gridfs: store files in MongoDB.
- couchdb, elasticsearch: other document stores.
- Apache Camel MongoDB component
Found a problem?
If something on this page doesn't match what Cameleer does, or you hit a bug while building
with it, please help fix it, whether you are a person or a coding agent:
open an issue that describes what you saw,
then fork the repository, fix it, add or update a test, run cargo test --workspace, and open
a pull request. CONTRIBUTING.md
explains the ground rules.