Skip to content

MongoDB

MongoDB doesn’t have SQL views, so PlotPress maps the “view” concept to named aggregation pipelines stored in the dashboard, plus optional Atlas SQL views when running on Atlas.

appdb:
driver: mongodb
dsn: mongodb+srv://reader:${MONGO_PASSWORD}@cluster.example.com/app?authSource=admin&readPreference=secondaryPreferred
allowed_users: [analysts]
timeout: 30s

Standard MongoDB connection-string format. Common parameters:

ParameterMeaning
authSourcethe DB to authenticate against
readPreferenceprimary, secondaryPreferred, nearest
tlstrue for Atlas / TLS-required clusters
// In mongosh
db.createUser({
user: "plotpress_reader",
pwd: "...",
roles: [{ role: "read", db: "app" }],
});

For non-Atlas MongoDB, PlotPress treats files in dashboards/<name>/pipelines/ as the primary data-access path. The file is a JSON aggregation pipeline:

// dashboards/sales/pipelines/monthly_revenue.json
[
{ "$match": { "invoice_date": { "$gte": ":start", "$lt": ":end" } } },
{ "$group": {
"_id": { "$dateTrunc": { "date": "$invoice_date", "unit": "month" } },
"revenue": { "$sum": "$amount" }
}},
{ "$project": { "_id": 0, "month": "$_id", "revenue": 1 } },
{ "$sort": { "month": 1 } }
]

Reference from a Plot block:

Plot.barY(data, { x: "month", y: "revenue" })

collection= names the source collection; pipeline files are dashboard-scoped.

When running against MongoDB Atlas with the Atlas SQL Federated Database, the view= syntax used everywhere else just works — point the DSN at the Atlas SQL endpoint and create SQL views over your collections.

For ad-hoc cases, drop a JSON pipeline file in queries/ instead of pipelines/. Same shape, but flagged as a workaround in the audit log (the same way SQL queries/ files are).

  • Type unification. MongoDB documents are heterogeneous; Plot blocks expect a uniform schema. Project to a fixed shape in the pipeline ($project with explicit fields) before returning.
  • ObjectId and dates. PlotPress serializes ObjectId as string and Date as RFC 3339 timestamp. Don’t return them as $type extended JSON — that ends up as nested objects on the frontend.
  • $lookup cost. Joins between large collections are expensive. Prefer pre-aggregated collections refreshed by a separate job.
  • No row-level security primitives. Use Realm rules or filter at the pipeline boundary, then gate the connection in connections.yaml.