zplCloud Blog

Connect a Local MongoDB as a Label Datasource with the zplCloud CLI

Filters become native query documents, executed by the agent in your network. The connection string stays on your machine.

4 min read zplCloud Team

No export, no copy of your collection in the cloud

MongoDB collection queried through the zplCloud CLI agent to print barcode labels

Product data, order items, serial numbers - if it already lives in MongoDB, exporting it to CSV so a label can print it is pure overhead, and the export is stale the moment it is written.

The zplCloud data hub connects the collection directly. A CLI agent in your network holds the connection string, the platform describes the query, and the agent returns only the matching documents. The database stays unreachable from the internet.

Architecture

zplcloud proxy keeps one outbound TLS connection to api.zplcloud.com. Nothing listens on your side, so there is no inbound port and no firewall exception. Query, sort and paging are pushed down: the agent builds a real MongoDB query and calls Find(filter).Sort(…).Skip(n).Limit(m). The collection is never downloaded.

Step 1 - start the agent with your MongoDB

# Multiple --mongo flags are allowed; the NAME is what you pick in the platform.
zplcloud proxy --agent "Lager" \
  --mongo LOCAL="mongodb://admin:…@127.0.0.1:27017/products" \
  --mongo PROD="mongodb://admin:…@mongo.internal.lan:27017/erp"

The connection string must include the database name - it is the part after the host, …:27017/products. Without it the agent has a server but no database to query.

Secrets are better kept out of shell history:

$env:ZPLCLOUD_MONGO_LOCAL_CONNECTION = "mongodb://admin:…@127.0.0.1:27017/products"
zplcloud proxy --agent "Lager"

The banner confirms what was registered: MongoDB servers: LOCAL, PROD. Authenticate against the platform with --api-key <key> or ZPLCLOUD_API_KEY; make it permanent with --service-install (systemd on Linux/Raspberry Pi, scheduled task on Windows) or with ZPLCLOUD_MONGO_LOCAL_CONNECTION in docker-compose.agent.yml.

Give the agent a read-only user scoped to the database it needs. The agent executes with that user, so MongoDB's own role model is the permission boundary.

Step 2 - create the datasource

In Data sources the agent appears under Remote SQL Server with a chip per MongoDB instance. Clicking it pre-fills the form.

FieldValue
NameLager-Artikel
TypeMongoDB
ServerLOCAL (the name from --mongo LOCAL=…)
Collectionproducts

Test pings the instance and returns server · database. Fields samples a document and lists the field names with their BSON types.

Field discovery works from a sample, which matters in a schemaless store: if the first documents lack a field that later documents have, it will not appear in the list. Add it manually in the binding if you know it exists.

Step 3 - how a filter is executed

The filter row you build in Query - column, operator, value - is translated into a MongoDB filter document and executed by the agent:

Operator in the UIMongoDB
contains{ ean: { $regex: "40063813" } }
starts with{ ean: { $regex: "^40063813" } }
={ ean: "40063813" }
> / <{ price: { $gt: 10 } } / { $lt: … }

Two consequences worth stating plainly:

  • There is no injection surface. A MongoDB filter is a BSON document - data, not a string that gets parsed as code. A value containing $ or {} is still just a value.
  • $regex without an anchor cannot use an index. contains on a large collection is a full scan. starts with produces ^…, which a normal index on that field can serve. On big collections, prefer it.

The hard limits (from the agent source)

LimitValue
Rows per request1000 - limit is clamped, the default is 100
Server selection timeout15 s - an unreachable replica set fails here, not after minutes
Executed operationread only: Find with sort, skip and limit

Larger result sets are paged: the platform requests page after page with a growing Skip, each capped at 1000 documents. Batch printing 10 000 labels therefore never holds more than one page in memory, on either side.

Note that Skip on a large offset makes MongoDB walk the skipped documents. For catalogs in the hundreds of thousands, an indexed sort field keeps that cheap; an unindexed sort will not.

Step 4 - use it in the designer and in Print Views

  • Designer → Test Data tab → Data source: pick the datasource, press Load, and every binding renders with real documents. Field lengths, missing values and encoding problems show up here rather than on the label roll.
  • Print Views → configuration → Data source (data hub): preview and printing use the live query. The operator never sees that MongoDB is behind it.

Failure modes

SymptomCause
Agent runs, no chip in the data hub--mongo name missing, or the API key belongs to another workspace
Test fails after ~15 sserver selection timeout - host unreachable from the agent machine, wrong port, or a replica set whose members advertise names the agent cannot resolve
Test fails instantly with auth errorwrong user/password, or the auth database differs from the data database (?authSource=admin)
Fields misses a fieldthe sampled document does not contain it - schemaless collections need a representative sample
Filter returns nothing on a value you can seetype mismatch: a numeric field compared against a string. Check the type in the field list

Plan

The data hub (MongoDB and SQL Server datasources through the CLI agent) is part of the Pro plan. See the pricing page.

Related

More articles