MongoDB Query Tester
Try MongoDB queries without a database. Paste documents (or use the sample products and orders), write a find() filter or an aggregation pipeline in normal mongosh syntax, and see the matching documents instantly, stage by stage if you like.
Last updated:
A JSON array is one collection; an object of arrays like {"products": [...], "orders": [...]} gives several collections for $lookup. Extended JSON ($oid, $date) and shell syntax (ObjectId(), ISODate()) both work.
How to use the MongoDB Query Tester
- Load documents: keep the sample products and orders, paste a JSON array (for example from mongoexport --jsonArray or Compass), or upload a .json file.
- Choose find() or aggregate() and pick the collection to query.
- Write the query in mongosh syntax, such as
{ price: { $lt: 50 } }, or click an example chip. - Read the results as JSON or as a table. In aggregate mode, use Show output after to inspect each stage.
- Copy the mongosh command to run the same query against your real database.
MongoDB query operator cheat sheet
| Operator | Matches documents where… | Example |
|---|---|---|
$eq / plain value | the field equals the value (or an array element does) | { status: "shipped" } |
$ne | the field is not equal, including documents without the field | { status: { $ne: "cancelled" } } |
$gt $gte $lt $lte | the value is in a range (same type only) | { price: { $gte: 10, $lt: 50 } } |
$in / $nin | the value is (not) one of a list | { category: { $in: ["home", "kitchen"] } } |
$exists | the field is present (true) or missing (false) | { discontinued: { $exists: true } } |
$type | the value has a BSON type | { price: { $type: "number" } } |
$regex or /re/ | a string matches a regular expression | { name: /^cast/i } |
$and $or $nor | combinations of whole filters | { $or: [ { stock: 0 }, { price: { $gt: 70 } } ] } |
$not | an operator expression is false | { price: { $not: { $gt: 50 } } } |
$all | an array contains every listed value | { tags: { $all: ["wood", "kitchen"] } } |
$elemMatch | one array element meets all conditions | { ratings: { $elemMatch: { user: "ana", score: 5 } } } |
$size | an array has exactly n elements | { ratings: { $size: 0 } } |
$expr | an aggregation expression is true (compare two fields) | { $expr: { $gt: ["$qty", "$stock"] } } |
Aggregation stages at a glance
| Stage | Purpose | Tip |
|---|---|---|
$match | Filter documents with the same syntax as find() | Put it first so later stages process fewer documents |
$project / $addFields | Reshape: keep, drop, rename or compute fields | $addFields keeps every existing field |
$group | Aggregate by a key with $sum, $avg, $min, $max, $push, $addToSet, $first, $last | _id: null groups all documents together |
$unwind | Output one document per array element | Add preserveNullAndEmptyArrays: true to keep empty arrays |
$lookup | Left outer join with another collection | The result is always an array; follow with $unwind for one match |
$sort, $skip, $limit | Order and paginate | Sort on a unique field too for stable paging |
$facet | Run several sub-pipelines on the same input | Great for a count plus a page of results in one query |
$bucket, $sortByCount, $count | Histograms, frequency tables and totals | $sortByCount: "$tags" after $unwind ranks tags |
Rules that often surprise people
- Type bracketing:
{ price: { $gt: "10" } }only compares strings, so it never matches numeric prices. Store and query numbers as numbers. - null matches missing:
{ discontinued: null }returns documents where the field is null or absent. Use{ $exists: false }or{ $type: "null" }to tell them apart. - Projections: you cannot mix
1and0in one projection, except_id: 0._idis included unless you exclude it. - Exact sub-document match:
{ dims: { w: 12, h: 20 } }requires the same fields in the same order; use dot notation such as{ "dims.w": 12 }to match one field. - Sorting arrays: an ascending sort on an array field uses its smallest element, a descending sort its largest.
- Dates: range queries on dates need real dates (
ISODate()or{"$date": ...}). ISO strings stored as plain text only compare as strings.
Frequently asked questions
Do I need a MongoDB server to use this?
No. The tester contains its own query engine written in JavaScript that follows MongoDB's matching, projection, sorting and aggregation rules, so it runs in your browser on the documents you paste. Nothing is sent to a server, which also makes it safe for sample data copied from production.
What syntax can I use?
Anything you would type in mongosh: unquoted field names, single or double quotes, regular expressions like /^abc/i, ObjectId("..."), ISODate("..."), new Date(...), NumberInt(...), comments and trailing commas. Strict JSON and MongoDB Extended JSON ($oid, $date, $numberLong) are accepted as well.
How does matching work with arrays?
As in MongoDB, a condition on an array field matches if any element satisfies it, so { tags: "camping" } finds documents whose tags array contains camping. Use $all to require several values, $size for an exact length, and $elemMatch when one element must satisfy several conditions at once. Dot notation such as "ratings.score" reaches into arrays of sub-documents.
How do I join two collections with $lookup?
Paste an object with one array per collection, for example {"orders": [...], "products": [...]}, choose the collection the pipeline runs on, and add a stage like { $lookup: { from: "products", localField: "productId", foreignField: "_id", as: "product" } }. The pipeline form with let and pipeline is supported too.
Will the results be identical to my MongoDB server?
For the supported operators the results follow MongoDB's documented behaviour, including type bracketing in comparisons, null matching missing fields and array sort keys. Differences can appear with features that need a server, such as text or geospatial indexes, collation, $where, writes, and the order of $group output, which MongoDB does not guarantee either. Numbers use JavaScript doubles, so NumberDecimal precision is not kept.
Why does my filter return no documents?
Common causes: comparing a string to a number ("42" does not equal 42 and range operators only compare values of the same type), dates stored as plain strings instead of ISODate or $date values, a field name typo or wrong letter case, or using an operator object where a nested document was meant. The error box explains syntax problems with the line and column.
Can I use my own exported data?
Yes. Paste or upload the output of mongoexport (both --jsonArray and the default one-document-per-line format), Compass exports, or any JSON array. Large files of several megabytes work, but the tester is designed for samples rather than full collections.
Are all the tools on FreeToolCabin tested for quality and accuracy?
Yes! Every tool on our site undergoes automated Q/A testing in real browser environments to ensure high precision, correct output, and zero errors. If you happen to spot a bug or have a suggestion, please contact us at [email protected] and our team will review it right away.