{ "description": "expressions", "schemaVersion": "1.4", "createEntities": [ { "client": { "id": "client0" } }, { "database": { "id": "database0", "client": "client0", "databaseName": "aggregate-corpus" } }, { "collection": { "id": "collection0", "database": "database0", "collectionName": "coll" } } ], "initialData": [ { "collectionName": "coll", "databaseName": "aggregate-corpus", "documents": [ { "_id": 1, "a": 10, "b": 3, "s": "x", "n": null, "f": false }, { "_id": 2, "a": 20, "b": 0, "s": "y", "f": true }, { "_id": 3, "a": -5, "b": 4, "s": "x", "n": 7, "f": false } ] } ], "tests": [ { "description": "a compound _id groups on every field", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "s": "$s", "f": "$f" }, "n": { "$sum": 1 } } }, { "$sort": { "_id.s": 1, "_id.f": 1 } } ] }, "expectResult": [ { "_id": { "s": "x", "f": false }, "n": 2 }, { "_id": { "s": "y", "f": true }, "n": 1 } ] } ] }, { "description": "a nested compound _id", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "outer": { "inner": "$s" } }, "n": { "$sum": 1 } } }, { "$sort": { "_id.outer.inner": 1 } } ] }, "expectResult": [ { "_id": { "outer": { "inner": "x" } }, "n": 2 }, { "_id": { "outer": { "inner": "y" } }, "n": 1 } ] } ] }, { "description": "$literal keeps a $-string from being a path", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$literal": "$s" }, "n": { "$sum": 1 } } } ] }, "expectResult": [ { "_id": "$s", "n": 3 } ] } ] }, { "description": "$literal of a document", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$literal": { "$sum": 1 } }, "n": { "$sum": 1 } } } ] }, "expectResult": [ { "_id": { "$sum": 1 }, "n": 3 } ] } ] }, { "description": "$add of a path and a constant", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$add": [ "$a", 1 ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": -4, "n": 1 }, { "_id": 11, "n": 1 }, { "_id": 21, "n": 1 } ] } ] }, { "description": "$subtract and $multiply", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": "$s", "d": { "$sum": { "$subtract": [ "$a", "$b" ] } }, "m": { "$sum": { "$multiply": [ "$a", 2 ] } } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "x", "d": -2, "m": 10 }, { "_id": "y", "d": 20, "m": 40 } ] } ] }, { "description": "$divide by zero is an error", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": null, "v": { "$sum": { "$divide": [ "$a", "$b" ] } } } } ] }, "expectError": { "isError": true, "errorCode": 4848401 } } ] }, { "description": "$divide and $mod", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$match": { "b": { "$gt": 0 } } }, { "$group": { "_id": "$s", "d": { "$push": { "$divide": [ "$a", "$b" ] } }, "m": { "$push": { "$mod": [ "$a", "$b" ] } } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "x", "d": [ 3.3333333333333335, -1.25 ], "m": [ 1, -1 ] } ] } ] }, { "description": "arithmetic over a missing field", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$add": [ "$missing", 1 ] }, "n": { "$sum": 1 } } } ] }, "expectResult": [ { "_id": null, "n": 3 } ] } ] }, { "description": "arithmetic over null", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": "$s", "v": { "$push": { "$add": [ "$n", 1 ] } } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "x", "v": [ null, 8 ] }, { "_id": "y", "v": [ null ] } ] } ] }, { "description": "$eq and $ne", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$eq": [ "$s", "x" ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": false, "n": 1 }, { "_id": true, "n": 2 } ] } ] }, { "description": "comparison across types follows canonical order", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$lt": [ "$a", "$s" ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": true, "n": 3 } ] } ] }, { "description": "$cmp returns the ordering", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": "$s", "v": { "$push": { "$cmp": [ "$a", "$b" ] } } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "x", "v": [ 1, -1 ] }, { "_id": "y", "v": [ 1 ] } ] } ] }, { "description": "$and and $or are truthy over non-booleans", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$and": [ "$a", "$f" ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": false, "n": 2 }, { "_id": true, "n": 1 } ] } ] }, { "description": "$not of a missing field", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$not": [ "$missing" ] }, "n": { "$sum": 1 } } } ] }, "expectResult": [ { "_id": true, "n": 3 } ] } ] }, { "description": "$cond in its array form", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$cond": [ { "$gt": [ "$a", 0 ] }, "positive", "negative" ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "negative", "n": 1 }, { "_id": "positive", "n": 2 } ] } ] }, { "description": "$cond in its document form", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$cond": { "if": "$f", "then": "yes", "else": "no" } }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "no", "n": 2 }, { "_id": "yes", "n": 1 } ] } ] }, { "description": "$ifNull falls through on missing and on null", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$ifNull": [ "$n", "fallback" ] }, "count": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": 7, "count": 1 }, { "_id": "fallback", "count": 2 } ] } ] }, { "description": "$switch picks the first matching branch", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$switch": { "branches": [ { "case": { "$lt": [ "$a", 0 ] }, "then": "neg" }, { "case": { "$lt": [ "$a", 15 ] }, "then": "small" } ], "default": "big" } }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": "big", "n": 1 }, { "_id": "neg", "n": 1 }, { "_id": "small", "n": 1 } ] } ] }, { "description": "$switch with no branch matching and no default is an error", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$switch": { "branches": [ { "case": false, "then": "never" } ] } }, "n": { "$sum": 1 } } } ] }, "expectError": { "isError": true, "errorCode": 40069 } } ] }, { "description": "an unknown expression operator is refused", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$bogusExpr": "$a" }, "n": { "$sum": 1 } } } ] }, "expectError": { "isError": true, "errorCode": 168 } } ] }, { "description": "two operators in one expression document are refused", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$add": [ "$a", 1 ], "$literal": 2 }, "n": { "$sum": 1 } } } ] }, "expectError": { "isError": true, "errorCode": 15983 } } ] }, { "description": "a nested expression inside an accumulator argument", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": null, "v": { "$max": { "$add": [ { "$multiply": [ "$a", 2 ] }, "$b" ] } } } } ] }, "expectResult": [ { "_id": null, "v": 40 } ] } ] }, { "description": "arithmetic over a non-numeric value is an error", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$add": [ "$s", 1 ] }, "n": { "$sum": 1 } } } ] }, "expectError": { "isError": true, "errorCode": 7157723 } } ] }, { "description": "$not takes a bare argument as well as an array", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$not": "$f" }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": false, "n": 1 }, { "_id": true, "n": 2 } ] } ] }, { "description": "$add of several operands", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$add": [ "$a", "$b", 100 ] }, "n": { "$sum": 1 } } }, { "$sort": { "_id": 1 } } ] }, "expectResult": [ { "_id": 99, "n": 1 }, { "_id": 113, "n": 1 }, { "_id": 120, "n": 1 } ] } ] }, { "description": "$subtract needs exactly two operands", "operations": [ { "object": "collection0", "name": "aggregate", "arguments": { "pipeline": [ { "$group": { "_id": { "$subtract": [ "$a" ] }, "n": { "$sum": 1 } } } ] }, "expectError": { "isError": true, "errorCode": 16020 } } ] } ] }