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.

Generate JSON →NDJSON details

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 $lookup and $group to 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