MongoDB test data generator
Nested documents built with dot-notation field names, exported as a JSON array or newline-delimited JSON, and loaded into a collection with a single mongoimport.
Nested documents from flat field names
MongoDB documents are rarely flat, and you do not have to post-process to get structure. Name a field with dots and the JSON export nests it:
Field name Document
--------------------------------------------------
name {
address.city "name": "Elena Rossi",
address.country "address": { "city": "Lyon",
account.plan "country": "France" },
account.seats "account": { "plan": "pro", "seats": 12 }
}
Types survive the trip: numbers stay numbers, booleans stay booleans, and a field with Blank % set produces a genuine null. That matters more in MongoDB than in a relational store, because a document database will happily accept a string where every other document has an integer, and you will not find out until an aggregation fails.
Loading a collection
# JSON array export mongoimport --db shop --collection customers \ --file customers.json --jsonArray --drop # NDJSON export — one document per line, streams mongoimport --db shop --collection customers \ --file customers.ndjson --drop
Use NDJSON for anything large. --jsonArray asks mongoimport to parse the whole file as one array, which means holding it in memory; the newline-delimited form streams document by document and has no such ceiling. For 100,000 documents the difference is noticeable, and NDJSON is the format mongoimport prefers anyway.
--drop replaces the collection, which is what you usually want when reseeding a development database and never what you want anywhere else.
_id, and whether to supply one
Leave _id out and MongoDB generates an ObjectId per document — fine, but the identifiers differ on every reseed, so nothing in a test can reference them.
Supplying your own makes fixtures addressable. A UUID field named _id gives you a stable string key that is identical on every machine using the same seed, so a test can navigate straight to a known document. The trade-off is that a random string primary key has worse insert locality than a monotonic ObjectId — irrelevant for a development fixture, worth knowing before you copy the pattern into production.
Arrays inside documents
Dot notation builds nested objects, not arrays — there is no field syntax for "three tags per document". Two practical routes:
- Generate a delimited string with a Custom List or Words field, then split it after import with a short aggregation pipeline or a script.
- Generate the child collection separately and either keep the reference-style shape (which many schemas want anyway) or use
$lookupand$groupto embed. Pull the parent IDs into a Custom List field on the child schema so references actually resolve.
The reference-style version is usually closer to a real schema than a deeply embedded one, so this constraint tends to push in a helpful direction.
Dates
The export writes ISO 8601 strings, not BSON date objects. mongoimport with the default JSON parsing stores them as strings, which sorts correctly but will not answer a range query the way a real date does. Convert after import when it matters:
db.customers.updateMany(
{ created_at: { $type: "string" } },
[{ $set: { created_at: { $toDate: "$created_at" } } }]
);
Schema validation
If your collection has a JSON Schema validator attached, a generated import is a good test of it. Set Blank % on fields the validator marks required and confirm the load is rejected rather than silently accepted — a validator nobody has ever seen reject anything is not evidence of correctness.
Common questions
How do I generate nested MongoDB documents?
Name fields with dot notation — address.city, address.country — and the JSON export nests them under a shared parent object. Types are preserved, so numbers and booleans arrive as numbers and booleans.
Should I import JSON or NDJSON?
NDJSON for anything large. --jsonArray parses the whole file as a single array in memory; newline-delimited JSON streams one document at a time and is what mongoimport prefers.
Can I set my own _id?
Yes — name a UUID field _id. That makes documents addressable from tests, because the same seed produces the same identifiers on every machine, unlike server-generated ObjectIds.
How do I generate an array field?
Dot notation builds objects, not arrays. Generate a delimited string and split it after import, or generate a separate child collection and reference the parent IDs through a Custom List field.
Why are my dates stored as strings?
The export writes ISO 8601 strings and mongoimport stores them as such. Convert them after import with an updateMany using $toDate if you need real BSON dates for range queries.
Related
- Sample JSON data — typed fixtures and nesting.
- NDJSON export — streaming-friendly output.
- PostgreSQL test data — the relational equivalent.
- Mock API data guide — serving these documents from a fake endpoint.