Matches values equal to the given value. { qty: 20 } is shorthand.
{ qty: { $eq: 20 } }Searchable reference of MongoDB query, update and aggregation operators and pipeline stages, each with example syntax and a link to the official documentation.
Free, no sign-up. Search runs in your browser and nothing you type is sent to any server.
214 operators
Matches values equal to the given value. { qty: 20 } is shorthand.
{ qty: { $eq: 20 } }Matches values not equal to the value, including documents without the field.
{ status: { $ne: 'A' } }Greater than.
{ qty: { $gt: 20 } }Greater than or equal to.
{ qty: { $gte: 20 } }Less than.
{ qty: { $lt: 20 } }Less than or equal to.
{ qty: { $lte: 20 } }Matches any of the values in the array.
{ status: { $in: ['A', 'D'] } }Matches none of the values, including documents without the field.
{ status: { $nin: ['A', 'D'] } }All conditions must match. Implicit when you list several fields.
{ $and: [{ a: 1 }, { b: { $gt: 2 } }] }At least one condition must match. Each branch can use its own index.
{ $or: [{ a: 1 }, { b: 2 }] }None of the conditions may match.
{ $nor: [{ a: 1 }, { b: 2 }] }Inverts an operator expression; also matches documents without the field.
{ price: { $not: { $gt: 1.99 } } }Matches documents that have (or lack) the field, even when its value is null.
{ email: { $exists: true } }Matches by BSON type name or number; arrays match if any element has the type.
{ zip: { $type: 'string' } }Uses aggregation expressions in a query, e.g. to compare two fields.
{ $expr: { $gt: ['$spent', '$budget'] } }Pattern match. Anchored, case-sensitive prefixes can use an index.
{ name: { $regex: '^acme', $options: 'i' } }Full-text search over a text index.
{ $text: { $search: 'coffee shop' } }Field value divided by divisor has the given remainder.
{ qty: { $mod: [4, 0] } }Matches documents that satisfy a JSON Schema.
{ $jsonSchema: { required: ['name'] } }Runs JavaScript per document. Slow; prefer $expr.
{ $where: 'this.a > this.b' }Array contains every listed value, in any order.
{ tags: { $all: ['red', 'blank'] } }At least one array element matches all the conditions together.
{ results: { $elemMatch: { score: { $gte: 80, $lt: 85 } } } }Array has exactly this many elements. Cannot take a range.
{ tags: { $size: 3 } }Geometry lies entirely within a shape.
{ loc: { $geoWithin: { $centerSphere: [[-73.9, 40.7], 0.001] } } }Geometry intersects the given GeoJSON geometry.
{ area: { $geoIntersects: { $geometry: { type: 'Point', coordinates: [1, 2] } } } }Sorted by distance from a point. Needs a geospatial index.
{ loc: { $near: { $geometry: point, $maxDistance: 500 } } }Like $near, using spherical geometry.
{ loc: { $nearSphere: { $geometry: point } } }All the given bit positions are 1.
{ flags: { $bitsAllSet: [1, 5] } }Any of the given bits are 1.
{ flags: { $bitsAnySet: 35 } }All the given bits are 0.
{ flags: { $bitsAllClear: [1, 5] } }Any of the given bits are 0.
{ flags: { $bitsAnyClear: 35 } }Sets field values, creating fields (and parents) as needed.
{ $set: { status: 'D', 'size.uom': 'in' } }Removes fields.
{ $unset: { tmp: '' } }Adds to a number; creates the field if missing.
{ $inc: { qty: -2, views: 1 } }Multiplies a number.
{ $mul: { price: 1.25 } }Updates only if the new value is smaller.
{ $min: { lowScore: 150 } }Updates only if the new value is larger.
{ $max: { highScore: 950 } }Renames a field.
{ $rename: { nmae: 'name' } }Sets values only when an upsert inserts a new document.
{ $setOnInsert: { createdAt: new Date() } }Sets a field to the current date or timestamp.
{ $currentDate: { lastModified: true } }Appends a value to an array.
{ $push: { scores: 89 } }Appends only if the value is not already present.
{ $addToSet: { tags: 'new' } }Removes the first (-1) or last (1) element.
{ $pop: { scores: -1 } }Removes all elements that match a value or condition.
{ $pull: { votes: { $gte: 6 } } }Removes all instances of the listed values.
{ $pullAll: { scores: [0, 5] } }Positional: updates the first element that matched the query.
{ $set: { 'grades.$': 82 } }All positional: updates every element of the array.
{ $inc: { 'grades.$[]': 10 } }Filtered positional: updates elements matching arrayFilters.
{ $set: { 'grades.$[g]': 100 } }, { arrayFilters: [{ g: { $gte: 100 } }] }Modifier for $push and $addToSet to add several values.
{ $push: { scores: { $each: [90, 92] } } }Modifier for $push: where to insert.
{ $push: { scores: { $each: [50], $position: 0 } } }Modifier for $push: keep only the first or last N elements.
{ $push: { recent: { $each: [x], $slice: -10 } } }Modifier for $push: sort the array after pushing.
{ $push: { quizzes: { $each: [q], $sort: { score: -1 } } } }Bitwise and / or / xor on an integer.
{ $bit: { flags: { or: 4 } } }Filters documents. Put it first so it can use an index.
{ $match: { status: 'A' } }Includes, excludes or computes fields.
{ $project: { name: 1, total: { $add: ['$a', '$b'] } } }Adds or overwrites fields, keeping the rest.
{ $addFields: { total: { $sum: '$items.price' } } }Alias of $addFields.
{ $set: { total: { $sum: '$items.price' } } }Removes fields.
{ $unset: ['password', 'tmp'] }Groups by a key and computes accumulators.
{ $group: { _id: '$status', n: { $sum: 1 } } }Sorts documents. Uses an index only near the start of the pipeline.
{ $sort: { createdAt: -1 } }Passes the first N documents.
{ $limit: 10 }Skips the first N documents.
{ $skip: 20 }Outputs one document with the number of input documents.
{ $count: 'total' }Outputs one document per array element.
{ $unwind: { path: '$items', preserveNullAndEmptyArrays: true } }Left outer join with another collection. Index the foreignField.
{ $lookup: { from: 'users', localField: 'uid', foreignField: '_id', as: 'user' } }Recursive lookup for trees and graphs.
{ $graphLookup: { from: 'emp', startWith: '$boss', connectFromField: 'boss', connectToField: 'name', as: 'chain' } }Appends documents from another collection.
{ $unionWith: { coll: 'archive', pipeline: [] } }Runs several sub-pipelines on the same input.
{ $facet: { byTag: [...], byPrice: [...] } }Groups into ranges you define.
{ $bucket: { groupBy: '$price', boundaries: [0, 100, 200], default: 'other' } }Groups into N evenly filled buckets.
{ $bucketAuto: { groupBy: '$price', buckets: 4 } }Groups by value and sorts by count, descending.
{ $sortByCount: '$tags' }Replaces each document with an embedded document.
{ $replaceRoot: { newRoot: '$address' } }Shorter form of $replaceRoot.
{ $replaceWith: '$address' }Picks N random documents.
{ $sample: { size: 100 } }Window functions: running totals, ranks, moving averages.
{ $setWindowFields: { partitionBy: '$state', sortBy: { date: 1 }, output: { run: { $sum: '$qty', window: { documents: ['unbounded', 'current'] } } } } }Fills gaps in a sequence of dates or numbers.
{ $densify: { field: 'ts', range: { step: 1, unit: 'hour', bounds: 'full' } } }Fills null or missing values.
{ $fill: { sortBy: { ts: 1 }, output: { price: { method: 'linear' } } } }Sorts by distance; must be the first stage.
{ $geoNear: { near: point, distanceField: 'dist' } }Restricts content by document-level conditions.
{ $redact: { $cond: [cond, '$$DESCEND', '$$PRUNE'] } }Writes the results to a collection, replacing it. Last stage.
{ $out: 'report' }Merges results into a collection. Last stage.
{ $merge: { into: 'report', whenMatched: 'merge', whenNotMatched: 'insert' } }Returns literal documents; use with db.aggregate().
{ $documents: [{ x: 1 }, { x: 2 }] }Collection statistics.
{ $collStats: { storageStats: {} } }How often each index is used. Find unused indexes.
{ $indexStats: {} }Opens a change stream; usually via watch().
db.coll.watch([...])Adds numbers, or a number of milliseconds to a date.
{ $add: ['$price', '$fee'] }Subtracts numbers or dates (date minus date gives milliseconds).
{ $subtract: ['$end', '$start'] }Multiplies numbers.
{ $multiply: ['$price', '$qty'] }Divides two numbers.
{ $divide: ['$total', '$count'] }Remainder of a division.
{ $mod: ['$a', 3] }Absolute value.
{ $abs: '$delta' }Rounds to a number of decimal places.
{ $round: ['$price', 2] }Truncates to a number of decimal places.
{ $trunc: ['$price', 0] }Smallest integer greater than or equal to the number.
{ $ceil: '$x' }Largest integer less than or equal to the number.
{ $floor: '$x' }Raises to a power.
{ $pow: ['$x', 2] }Square root.
{ $sqrt: '$x' }e raised to the power.
{ $exp: '$x' }Natural logarithm.
{ $ln: '$x' }Base-10 logarithm.
{ $log10: '$x' }Logarithm in any base.
{ $log: ['$x', 2] }Element at an index; negative counts from the end.
{ $arrayElemAt: ['$items', 0] }First element of an array.
{ $first: '$items' }Last element of an array.
{ $last: '$items' }Keeps the elements that match a condition.
{ $filter: { input: '$items', as: 'i', cond: { $gt: ['$$i.qty', 0] } } }Applies an expression to each element.
{ $map: { input: '$items', as: 'i', in: '$$i.price' } }Folds an array into a single value.
{ $reduce: { input: '$xs', initialValue: 0, in: { $add: ['$$value', '$$this'] } } }Number of elements.
{ $size: '$items' }True if the value is in the array.
{ $in: ['red', '$colors'] }Index of the first occurrence, or -1.
{ $indexOfArray: ['$items', 'x'] }True if the value is an array.
{ $isArray: '$x' }Joins arrays.
{ $concatArrays: ['$a', '$b'] }A subset of an array.
{ $slice: ['$items', 5] }Reverses an array.
{ $reverseArray: '$items' }Sorts an array.
{ $sortArray: { input: '$items', sortBy: { price: 1 } } }Generates a sequence of integers.
{ $range: [0, 10, 2] }Transposes arrays into an array of pairs.
{ $zip: { inputs: ['$a', '$b'] } }Converts [k, v] pairs or {k, v} documents to an object.
{ $arrayToObject: [[['k', 'v']]] }Converts an object to an array of {k, v}.
{ $objectToArray: '$attrs' }First N elements of an array.
{ $firstN: { input: '$xs', n: 3 } }Last N elements of an array.
{ $lastN: { input: '$xs', n: 3 } }N largest values.
{ $maxN: { input: '$scores', n: 3 } }N smallest values.
{ $minN: { input: '$scores', n: 3 } }True if the values are equal.
{ $eq: ['$a', '$b'] }True if the values differ.
{ $ne: ['$a', '$b'] }Greater than.
{ $gt: ['$qty', 250] }Greater than or equal to.
{ $gte: ['$qty', 250] }Less than.
{ $lt: ['$qty', 250] }Less than or equal to.
{ $lte: ['$qty', 250] }Returns -1, 0 or 1.
{ $cmp: ['$a', '$b'] }True if all expressions are true.
{ $and: [expr1, expr2] }True if any expression is true.
{ $or: [expr1, expr2] }Negates a boolean.
{ $not: [expr] }If / then / else.
{ $cond: { if: { $gte: ['$qty', 250] }, then: 30, else: 20 } }First value that is not null or missing.
{ $ifNull: ['$nickname', '$name', 'Anonymous'] }Multi-way branch.
{ $switch: { branches: [{ case: expr, then: v }], default: d } }Joins strings.
{ $concat: ['$first', ' ', '$last'] }Lowercases a string.
{ $toLower: '$email' }Uppercases a string.
{ $toUpper: '$code' }Removes whitespace (or given characters) from both ends.
{ $trim: { input: '$name' } }Trims the start.
{ $ltrim: { input: '$name' } }Trims the end.
{ $rtrim: { input: '$name' } }Splits a string into an array.
{ $split: ['$path', '/'] }Substring by code points.
{ $substrCP: ['$name', 0, 3] }Length in code points.
{ $strLenCP: '$name' }Index of a substring, or -1.
{ $indexOfCP: ['$name', 'a'] }Case-insensitive comparison: -1, 0 or 1.
{ $strcasecmp: ['$a', '$b'] }True if the regex matches.
{ $regexMatch: { input: '$email', regex: /@acme\.com$/ } }First regex match and its captures.
{ $regexFind: { input: '$text', regex: /\d+/ } }All regex matches.
{ $regexFindAll: { input: '$text', regex: /\d+/ } }Replaces the first occurrence.
{ $replaceOne: { input: '$s', find: 'a', replacement: 'b' } }Replaces every occurrence.
{ $replaceAll: { input: '$s', find: 'a', replacement: 'b' } }Formats a date as a string.
{ $dateToString: { format: '%Y-%m-%d', date: '$at', timezone: 'Europe/Paris' } }Parses a string into a date.
{ $dateFromString: { dateString: '$s' } }Adds a time unit to a date.
{ $dateAdd: { startDate: '$at', unit: 'day', amount: 7 } }Subtracts a time unit from a date.
{ $dateSubtract: { startDate: '$at', unit: 'month', amount: 1 } }Difference between two dates in a unit.
{ $dateDiff: { startDate: '$a', endDate: '$b', unit: 'day' } }Rounds a date down to a unit.
{ $dateTrunc: { date: '$at', unit: 'week' } }Builds a date from parts.
{ $dateFromParts: { year: 2024, month: 1, day: 31 } }Splits a date into parts.
{ $dateToParts: { date: '$at' } }Year of a date.
{ $year: '$at' }Month (1-12).
{ $month: '$at' }Day of the month (1-31).
{ $dayOfMonth: '$at' }Day of the week (1 = Sunday).
{ $dayOfWeek: '$at' }Hour (0-23).
{ $hour: '$at' }ISO 8601 week number.
{ $isoWeek: '$at' }BSON type name of a value.
{ $type: '$x' }Converts with error and null handling.
{ $convert: { input: '$x', to: 'int', onError: 0, onNull: 0 } }Converts to a string.
{ $toString: '$_id' }Converts to a 32-bit integer.
{ $toInt: '$qty' }Converts to a 64-bit integer.
{ $toLong: '$qty' }Converts to a double.
{ $toDouble: '$price' }Converts to Decimal128.
{ $toDecimal: '$price' }Converts to a boolean.
{ $toBool: '$flag' }Converts to a date.
{ $toDate: '$ts' }Converts a 24-hex string to an ObjectId.
{ $toObjectId: '$idString' }True for int, long, double or decimal.
{ $isNumber: '$x' }Combines documents; later fields win.
{ $mergeObjects: ['$defaults', '$overrides'] }Reads a field, including names with dots or $.
{ $getField: 'price.usd' }Sets a field, including names with dots or $.
{ $setField: { field: 'a.b', input: '$$ROOT', value: 1 } }Defines variables for an expression.
{ $let: { vars: { t: { $add: ['$a', '$b'] } }, in: { $multiply: ['$$t', 2] } } }Returns a value without parsing it.
{ $literal: '$notAFieldPath' }Elements in either array, without duplicates.
{ $setUnion: ['$a', '$b'] }Elements in both arrays.
{ $setIntersection: ['$a', '$b'] }Elements in the first array only.
{ $setDifference: ['$a', '$b'] }True if both arrays have the same distinct elements.
{ $setEquals: ['$a', '$b'] }True if every element of the first is in the second.
{ $setIsSubset: ['$a', '$b'] }True if any element is true.
{ $anyElementTrue: ['$flags'] }True if no element is false, null, 0 or undefined.
{ $allElementsTrue: ['$flags'] }Total of numeric values; { $sum: 1 } counts documents.
{ $sum: '$qty' } { $sum: 1 }Average of numeric values.
{ $avg: '$price' }Smallest value.
{ $min: '$price' }Largest value.
{ $max: '$price' }Number of documents in the group.
{ $count: {} }Array of all values.
{ $push: '$item' }Array of distinct values.
{ $addToSet: '$tag' }Value from the first document in the group (sort first).
{ $first: '$name' }Value from the last document in the group.
{ $last: '$name' }Top element by a sort order.
{ $top: { sortBy: { score: -1 }, output: '$name' } }Bottom element by a sort order.
{ $bottom: { sortBy: { score: -1 }, output: '$name' } }Top N elements by a sort order.
{ $topN: { n: 3, sortBy: { score: -1 }, output: '$name' } }Bottom N elements by a sort order.
{ $bottomN: { n: 3, sortBy: { score: -1 }, output: '$name' } }Population standard deviation.
{ $stdDevPop: '$score' }Sample standard deviation.
{ $stdDevSamp: '$score' }Merges the documents of the group into one.
{ $mergeObjects: '$attrs' }Rank with gaps for ties.
{ $rank: {} }Rank without gaps.
{ $denseRank: {} }Row number in the partition.
{ $documentNumber: {} }Value from a document N positions away.
{ $shift: { output: '$qty', by: -1, default: 0 } }Rate of change.
{ $derivative: { input: '$odometer', unit: 'hour' } }Area under the curve.
{ $integral: { input: '$kw', unit: 'hour' } }Exponential moving average.
{ $expMovingAvg: { input: '$price', N: 20 } }Last observation carried forward over nulls.
{ $locf: '$price' }Linear interpolation over nulls.
{ $linearFill: '$price' }MotionQL's aggregation editor previews every stage as you build it, with the full operator library and templates. Pro is free for a year.
Build or parse mongodb:// and mongodb+srv:// URIs. Split a pasted URI into hosts, credentials and options, catch common mistakes, and copy a correctly encoded string with the password masked.
Open toolDecode a MongoDB ObjectId into its creation time, random value and counter, decode many at once, or generate ObjectIds for any date to query by time range.
Open toolConvert MongoDB documents between canonical Extended JSON, relaxed Extended JSON and mongosh shell syntax, keeping BSON types like ObjectId, Date, Long and Decimal128 intact.
Open toolPaste a document to get its exact BSON size in bytes, see how close it is to MongoDB's 16 MB document limit, and find the fields taking up the most space.
Open toolPaste the output of explain() to see the plan as a tree, catch collection scans and in-memory sorts, compare documents examined with documents returned, and get an index suggestion.
Open tool