diff --git a/.gitmodules b/.gitmodules index 5f09a786..3f7efd4c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ -[submodule "packages/mql-typescript/mongo-php-library"] - path = packages/mql-typescript/mongo-php-library - url = https://github.com/mongodb-js/mongo-php-library +[submodule "packages/mql-typescript/mql-specifications"] + path = packages/mql-typescript/mql-specifications + url = https://github.com/mongodb/mql-specifications.git diff --git a/packages/mql-typescript/.depcheckrc b/packages/mql-typescript/.depcheckrc index 1e94b37d..c06ee3cd 100644 --- a/packages/mql-typescript/.depcheckrc +++ b/packages/mql-typescript/.depcheckrc @@ -4,7 +4,6 @@ ignores: - '@types/chai' - '@types/sinon-chai' - 'sinon' - - 'json-schema-to-zod' ignore-patterns: - 'dist' - 'mongo-php-library' diff --git a/packages/mql-typescript/.eslintignore b/packages/mql-typescript/.eslintignore index 35b733e8..3cb2ffcd 100644 --- a/packages/mql-typescript/.eslintignore +++ b/packages/mql-typescript/.eslintignore @@ -1,3 +1,4 @@ .nyc-output dist mongo-php-library +mql-specifications diff --git a/packages/mql-typescript/.prettierignore b/packages/mql-typescript/.prettierignore index 4804f298..8ffeec40 100644 --- a/packages/mql-typescript/.prettierignore +++ b/packages/mql-typescript/.prettierignore @@ -2,3 +2,4 @@ dist coverage mongo-php-library +mql-specifications diff --git a/packages/mql-typescript/mongo-php-library b/packages/mql-typescript/mongo-php-library deleted file mode 160000 index 4a2867b1..00000000 --- a/packages/mql-typescript/mongo-php-library +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 4a2867b1267c96190ccf7e813f21a9d7a00236cc diff --git a/packages/mql-typescript/mql-specifications b/packages/mql-typescript/mql-specifications new file mode 160000 index 00000000..a02ba4b8 --- /dev/null +++ b/packages/mql-typescript/mql-specifications @@ -0,0 +1 @@ +Subproject commit a02ba4b86c15d6b0f24cbb1d0ad3dd6e1cfba69d diff --git a/packages/mql-typescript/out/schema.d.ts b/packages/mql-typescript/out/schema.d.ts index 9163ee0d..b084a7b1 100644 --- a/packages/mql-typescript/out/schema.d.ts +++ b/packages/mql-typescript/out/schema.d.ts @@ -19,7 +19,7 @@ type RecordWithStaticFields, TValue> = T & { // TBD: Nested fields type AFieldPath = KeysOfAType & string; -type FieldExpression = { [k: string]: FieldPath }; +type FieldExpression = { [k: string]: Expression }; type MultiAnalyzerSpec = { value: KeysOfAType; @@ -82,6 +82,7 @@ export namespace Aggregation.Accumulator { /** * Returns an array of unique expression values for each group. Order of the array elements is undefined. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addToSet/} */ $addToSet: Expression; @@ -95,6 +96,7 @@ export namespace Aggregation.Accumulator { /** * Returns an average of numerical values. Ignores non-numeric values. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/} */ $avg: ResolvesToNumber; @@ -107,7 +109,7 @@ export namespace Aggregation.Accumulator { export interface $bottom { /** * Returns the bottom element within a group according to the specified sort order. - * New in MongoDB 5.2: Available in the $group and $setWindowFields stages. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom/} */ $bottom: { @@ -130,8 +132,8 @@ export namespace Aggregation.Accumulator { export interface $bottomN { /** * Returns an aggregation of the bottom n elements within a group, according to the specified sort order. If the group contains fewer than n elements, $bottomN returns all elements in the group. - * New in MongoDB 5.2. * Available in the $group and $setWindowFields stages. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN/} */ $bottomN: { @@ -152,6 +154,25 @@ export namespace Aggregation.Accumulator { }; } + /** + * A type describing the `$concatArrays` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/} + */ + export interface $concatArrays { + /** + * Concatenates arrays to return the concatenated array. + * New in MongoDB 4.4. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/} + */ + $concatArrays: [ + /** + * An array of expressions that resolve to an array. + * If any argument resolves to a value of null or refers to a field that is missing, `$concatArrays` returns `null`. + */ + ...ResolvesToArray[], + ]; + } + /** * A type describing the `$count` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator/} @@ -281,6 +302,7 @@ export namespace Aggregation.Accumulator { /** * Returns the result of an expression for the first document in a group or window. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/first/} */ $first: Expression; @@ -295,6 +317,7 @@ export namespace Aggregation.Accumulator { * Returns an aggregation of the first n elements within a group. * The elements returned are meaningful only if in a specified sort order. * If the group contains fewer than n elements, $firstN returns all elements in the group. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN/} */ $firstN: { @@ -339,6 +362,7 @@ export namespace Aggregation.Accumulator { /** * Returns the result of an expression for the last document in a group or window. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/last/} */ $last: Expression; @@ -353,13 +377,14 @@ export namespace Aggregation.Accumulator { * Returns an aggregation of the last n elements within a group. * The elements returned are meaningful only if in a specified sort order. * If the group contains fewer than n elements, $lastN returns all elements in the group. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN/} */ $lastN: { /** * An expression that resolves to the array from which to return n elements. */ - input: Expression; + input: ResolvesToArray; /** * An expression that resolves to a positive integer. The integer specifies the number of array elements that $firstN returns. @@ -404,6 +429,7 @@ export namespace Aggregation.Accumulator { /** * Returns the maximum value that results from applying an expression to each document. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/max/} */ $max: Expression; @@ -416,6 +442,7 @@ export namespace Aggregation.Accumulator { export interface $maxN { /** * Returns the n largest values in an array. Distinct from the $maxN accumulator. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN/} */ $maxN: { @@ -438,11 +465,11 @@ export namespace Aggregation.Accumulator { export interface $median { /** * Returns an approximation of the median, the 50th percentile, as a scalar value. - * New in MongoDB 7.0. * This operator is available as an accumulator in these stages: * $group * $setWindowFields * It is also available as an aggregation expression. + * New in MongoDB 7.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/} */ $median: { @@ -465,6 +492,7 @@ export namespace Aggregation.Accumulator { export interface $mergeObjects { /** * Combines multiple documents into a single document. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/} */ $mergeObjects: ResolvesToObject; @@ -478,11 +506,44 @@ export namespace Aggregation.Accumulator { /** * Returns the minimum value that results from applying an expression to each document. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/min/} */ $min: Expression; } + /** + * A type describing the `$minMaxScaler` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minMaxScaler/} + */ + export interface $minMaxScaler { + /** + * Normalizes a numeric expression within a window of values. By default, values can range + * between zero and one. The smallest value becomes zero, the largest value becomes one, and + * all other values scale proportionally in between. You can also specify a custom minimum + * and maximum value for the normalized output range. + * Available only in the $setWindowFields stage. + * New in MongoDB 8.2. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minMaxScaler/} + */ + $minMaxScaler: { + /** + * Numeric expression containing the value that you want to normalize. + */ + input: ResolvesToNumber; + + /** + * Minimum value that you want in the output. If omitted, defaults to 0. + */ + min?: Number; + + /** + * Maximum value that you want in the output. If omitted, defaults to 1. + */ + max?: Number; + }; + } + /** * A type describing the `$minN` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN/} @@ -490,6 +551,7 @@ export namespace Aggregation.Accumulator { export interface $minN { /** * Returns the n smallest values in an array. Distinct from the $minN accumulator. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN/} */ $minN: { @@ -512,11 +574,11 @@ export namespace Aggregation.Accumulator { export interface $percentile { /** * Returns an array of scalar values that correspond to specified percentile values. - * New in MongoDB 7.0. * This operator is available as an accumulator in these stages: * $group * $setWindowFields * It is also available as an aggregation expression. + * New in MongoDB 7.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/} */ $percentile: { @@ -546,6 +608,7 @@ export namespace Aggregation.Accumulator { /** * Returns an array of values that result from applying an expression to each document. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/push/} */ $push: Expression; @@ -564,6 +627,24 @@ export namespace Aggregation.Accumulator { $rank: Record; } + /** + * A type describing the `$setUnion` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/} + */ + export interface $setUnion { + /** + * Takes two or more arrays and returns an array containing the elements that appear in any input array. + * New in MongoDB 4.4. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/} + */ + $setUnion: [ + /** + * An array of expressions that resolve to an array. + */ + ...ResolvesToArray[], + ]; + } + /** * A type describing the `$shift` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift/} @@ -607,6 +688,7 @@ export namespace Aggregation.Accumulator { * Calculates the population standard deviation of the input values. Use if the values encompass the entire population of data you want to represent and do not wish to generalize about a larger population. $stdDevPop ignores non-numeric values. * If the values represent only a sample of a population of data from which to generalize about the population, use $stdDevSamp instead. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/} */ $stdDevPop: ResolvesToNumber; @@ -621,6 +703,7 @@ export namespace Aggregation.Accumulator { * Calculates the sample standard deviation of the input values. Use if the values encompass a sample of a population of data from which to generalize about the population. $stdDevSamp ignores non-numeric values. * If the values represent the entire population of data or you do not wish to generalize about a larger population, use $stdDevPop instead. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/} */ $stdDevSamp: ResolvesToNumber; @@ -634,6 +717,7 @@ export namespace Aggregation.Accumulator { /** * Returns a sum of numerical values. Ignores non-numeric values. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/} */ $sum: ResolvesToNumber; @@ -646,8 +730,8 @@ export namespace Aggregation.Accumulator { export interface $top { /** * Returns the top element within a group according to the specified sort order. - * New in MongoDB 5.2. * Available in the $group and $setWindowFields stages. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/top/} */ $top: { @@ -670,8 +754,8 @@ export namespace Aggregation.Accumulator { export interface $topN { /** * Returns an aggregation of the top n fields within a group, according to the specified sort order. - * New in MongoDB 5.2. * Available in the $group and $setWindowFields stages. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN/} */ $topN: { @@ -700,6 +784,7 @@ export namespace Aggregation.Expression { export interface $abs { /** * Returns the absolute value of a number. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/abs/} */ $abs: ResolvesToNumber; @@ -712,6 +797,7 @@ export namespace Aggregation.Expression { export interface $acos { /** * Returns the inverse cosine (arc cosine) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/acos/} */ $acos: ResolvesToNumber; @@ -724,6 +810,7 @@ export namespace Aggregation.Expression { export interface $acosh { /** * Returns the inverse hyperbolic cosine (hyperbolic arc cosine) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/acosh/} */ $acosh: ResolvesToNumber; @@ -736,6 +823,7 @@ export namespace Aggregation.Expression { export interface $add { /** * Adds numbers to return the sum, or adds numbers and a date to return a new date. If adding numbers and a date, treats the numbers as milliseconds. Accepts any number of argument expressions, but at most, one expression can resolve to a date. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/add/} */ $add: [ @@ -753,6 +841,7 @@ export namespace Aggregation.Expression { export interface $allElementsTrue { /** * Returns true if no element of a set evaluates to false, otherwise, returns false. Accepts a single argument expression. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/allElementsTrue/} */ $allElementsTrue: [expression: ResolvesToArray]; @@ -765,6 +854,7 @@ export namespace Aggregation.Expression { export interface $and { /** * Returns true only when all its expressions evaluate to true. Accepts any number of argument expressions. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/and/} */ $and: [ @@ -785,6 +875,7 @@ export namespace Aggregation.Expression { export interface $anyElementTrue { /** * Returns true if any elements of a set evaluate to true; otherwise, returns false. Accepts a single argument expression. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/anyElementTrue/} */ $anyElementTrue: [expression: ResolvesToArray]; @@ -797,6 +888,7 @@ export namespace Aggregation.Expression { export interface $arrayElemAt { /** * Returns the element at the specified array index. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayElemAt/} */ $arrayElemAt: [array: ResolvesToArray, idx: ResolvesToInt]; @@ -809,6 +901,7 @@ export namespace Aggregation.Expression { export interface $arrayToObject { /** * Converts an array of key value pairs to a document. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/arrayToObject/} */ $arrayToObject: [array: ResolvesToArray]; @@ -821,6 +914,7 @@ export namespace Aggregation.Expression { export interface $asin { /** * Returns the inverse sin (arc sine) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/asin/} */ $asin: ResolvesToNumber; @@ -833,6 +927,7 @@ export namespace Aggregation.Expression { export interface $asinh { /** * Returns the inverse hyperbolic sine (hyperbolic arc sine) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/asinh/} */ $asinh: ResolvesToNumber; @@ -845,6 +940,7 @@ export namespace Aggregation.Expression { export interface $atan { /** * Returns the inverse tangent (arc tangent) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan/} */ $atan: ResolvesToNumber; @@ -857,6 +953,7 @@ export namespace Aggregation.Expression { export interface $atan2 { /** * Returns the inverse tangent (arc tangent) of y / x in radians, where y and x are the first and second values passed to the expression respectively. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/atan2/} */ $atan2: [ @@ -877,6 +974,7 @@ export namespace Aggregation.Expression { export interface $atanh { /** * Returns the inverse hyperbolic tangent (hyperbolic arc tangent) of a value in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/atanh/} */ $atanh: ResolvesToNumber; @@ -890,6 +988,7 @@ export namespace Aggregation.Expression { /** * Returns an average of numerical values. Ignores non-numeric values. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg/} */ $avg: [...ResolvesToNumber[]]; @@ -902,6 +1001,7 @@ export namespace Aggregation.Expression { export interface $binarySize { /** * Returns the size of a given string or binary data value's content in bytes. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/binarySize/} */ $binarySize: ResolvesToString | ResolvesToBinData | ResolvesToNull; @@ -959,6 +1059,68 @@ export namespace Aggregation.Expression { $bitXor: [...(ResolvesToInt | ResolvesToLong)[]]; } + /** + * A type describing the `$bottom` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom-array-operator/} + */ + export interface $bottom { + /** + * Returns the bottom element within an array according to the specified sort order. + * New in MongoDB 7.0. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom-array-operator/} + */ + $bottom: { + /** + * Specifies the order of results, with syntax similar to $sort. + */ + sortBy: SortBy; + + /** + * Represents the output for each element in the input array and can be any expression. + */ + output: Expression; + + /** + * An expression that resolves to the array from which to return the bottom element. + */ + input: ResolvesToArray; + }; + } + + /** + * A type describing the `$bottomN` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN-array-operator/} + */ + export interface $bottomN { + /** + * Returns an aggregation of the bottom n elements within an array, according to the specified sort order. + * If the array contains fewer than n elements, $bottomN returns all elements in the array. + * New in MongoDB 7.0. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN-array-operator/} + */ + $bottomN: { + /** + * An expression that resolves to a positive integer. The integer specifies the number of array elements that $bottomN returns. + */ + n: ResolvesToInt; + + /** + * Specifies the order of results, with syntax similar to $sort. + */ + sortBy: SortBy; + + /** + * Represents the output for each element in the input array and can be any expression. + */ + output: Expression; + + /** + * An expression that resolves to the array from which to return the bottom n elements. + */ + input: ResolvesToArray; + }; + } + /** * A type describing the `$bsonSize` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bsonSize/} @@ -966,6 +1128,7 @@ export namespace Aggregation.Expression { export interface $bsonSize { /** * Returns the size in bytes of a given document (i.e. BSON type Object) when encoded as BSON. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bsonSize/} */ $bsonSize: ResolvesToObject | ResolvesToNull; @@ -978,6 +1141,7 @@ export namespace Aggregation.Expression { export interface $case { /** * Represents a single case in a $switch expression + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/} */ $case: { @@ -1000,6 +1164,7 @@ export namespace Aggregation.Expression { export interface $ceil { /** * Returns the smallest integer greater than or equal to the specified number. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/ceil/} */ $ceil: ResolvesToNumber; @@ -1012,6 +1177,7 @@ export namespace Aggregation.Expression { export interface $cmp { /** * Returns 0 if the two values are equivalent, 1 if the first value is greater than the second, and -1 if the first value is less than the second. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/cmp/} */ $cmp: [expression1: Expression, expression2: Expression]; @@ -1024,6 +1190,7 @@ export namespace Aggregation.Expression { export interface $concat { /** * Concatenates any number of strings. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/concat/} */ $concat: [...ResolvesToString[]]; @@ -1036,6 +1203,7 @@ export namespace Aggregation.Expression { export interface $concatArrays { /** * Concatenates arrays to return the concatenated array. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/} */ $concatArrays: [...ResolvesToArray[]]; @@ -1048,6 +1216,7 @@ export namespace Aggregation.Expression { export interface $cond { /** * A ternary operator that evaluates one expression, and depending on the result, returns the value of one of the other two expressions. Accepts either three expressions in an ordered list or three named parameters. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/cond/} */ $cond: { if: ResolvesToBool; then: Expression; else: Expression }; @@ -1059,7 +1228,11 @@ export namespace Aggregation.Expression { */ export interface $convert { /** - * Converts a value to a specified type. + * Converts a value to a specified type. Any type can be converted to string. + * If the optional base argument is specified, $convert interprets the input string as a + * number in the given base and converts it to a decimal, or converts a numeric value to a + * string representation in that base. Supported bases are 2 (binary), 8 (octal), 10 + * (decimal), and 16 (hexadecimal). * New in MongoDB 4.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/convert/} */ @@ -1078,6 +1251,17 @@ export namespace Aggregation.Expression { * If unspecified, $convert returns null if the input is null or missing. */ onNull?: Expression; + + /** + * The numeric base to use when converting between strings and integers. Must be one of + * 2 (binary), 8 (octal), 10 (decimal), or 16 (hexadecimal). + * When converting a string to a number, $convert interprets the string as a number in + * the given base and returns the decimal equivalent. + * When converting a number to a string, $convert returns the string representation of + * the number in the given base. + * If unspecified, $convert uses base 10. + */ + base?: ResolvesToInt; }; } @@ -1088,6 +1272,7 @@ export namespace Aggregation.Expression { export interface $cos { /** * Returns the cosine of a value that is measured in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/cos/} */ $cos: ResolvesToNumber; @@ -1100,11 +1285,25 @@ export namespace Aggregation.Expression { export interface $cosh { /** * Returns the hyperbolic cosine of a value that is measured in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/cosh/} */ $cosh: ResolvesToNumber; } + /** + * A type describing the `$createObjectId` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/createObjectId/} + */ + export interface $createObjectId { + /** + * Returns a random object ID + * New in MongoDB 4.4. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/createObjectId/} + */ + $createObjectId: Record; + } + /** * A type describing the `$dateAdd` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateAdd/} @@ -1112,6 +1311,7 @@ export namespace Aggregation.Expression { export interface $dateAdd { /** * Adds a number of time units to a date object. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateAdd/} */ $dateAdd: { @@ -1143,6 +1343,7 @@ export namespace Aggregation.Expression { export interface $dateDiff { /** * Returns the difference between two dates. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateDiff/} */ $dateDiff: { @@ -1186,6 +1387,7 @@ export namespace Aggregation.Expression { export interface $dateFromParts { /** * Constructs a BSON Date object given the date's constituent parts. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromParts/} */ $dateFromParts: { @@ -1253,6 +1455,7 @@ export namespace Aggregation.Expression { export interface $dateFromString { /** * Converts a date/time string to a date object. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateFromString/} */ $dateFromString: { @@ -1293,6 +1496,7 @@ export namespace Aggregation.Expression { export interface $dateSubtract { /** * Subtracts a number of time units from a date object. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateSubtract/} */ $dateSubtract: { @@ -1324,6 +1528,7 @@ export namespace Aggregation.Expression { export interface $dateToParts { /** * Returns a document containing the constituent parts of a date. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToParts/} */ $dateToParts: { @@ -1351,6 +1556,7 @@ export namespace Aggregation.Expression { export interface $dateToString { /** * Returns the date as a formatted string. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateToString/} */ $dateToString: { @@ -1385,6 +1591,7 @@ export namespace Aggregation.Expression { export interface $dateTrunc { /** * Truncates a date. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dateTrunc/} */ $dateTrunc: { @@ -1425,6 +1632,7 @@ export namespace Aggregation.Expression { export interface $dayOfMonth { /** * Returns the day of the month for a date as a number between 1 and 31. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfMonth/} */ $dayOfMonth: { @@ -1447,6 +1655,7 @@ export namespace Aggregation.Expression { export interface $dayOfWeek { /** * Returns the day of the week for a date as a number between 1 (Sunday) and 7 (Saturday). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfWeek/} */ $dayOfWeek: { @@ -1469,6 +1678,7 @@ export namespace Aggregation.Expression { export interface $dayOfYear { /** * Returns the day of the year for a date as a number between 1 and 366 (leap year). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/dayOfYear/} */ $dayOfYear: { @@ -1491,11 +1701,39 @@ export namespace Aggregation.Expression { export interface $degreesToRadians { /** * Converts a value from degrees to radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/degreesToRadians/} */ $degreesToRadians: ResolvesToNumber; } + /** + * A type describing the `$deserializeEJSON` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/} + */ + export interface $deserializeEJSON { + /** + * Converts Extended JSON (EJSON) format to native BSON values. Use this expression to + * transform EJSON type wrappers into their corresponding BSON types after parsing a JSON + * string with $convert. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/} + */ + $deserializeEJSON: { + /** + * The Extended JSON value to convert to native BSON format. This should be a BSON + * document containing EJSON type wrappers. + */ + input: ResolvesToObject; + + /** + * The value to return if the operation encounters an error during conversion. + * If unspecified, the operation throws an error and stops. + */ + onError?: Expression; + }; + } + /** * A type describing the `$divide` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/divide/} @@ -1503,6 +1741,7 @@ export namespace Aggregation.Expression { export interface $divide { /** * Returns the result of dividing the first number by the second. Accepts two argument expressions. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/divide/} */ $divide: [ @@ -1521,6 +1760,7 @@ export namespace Aggregation.Expression { export interface $eq { /** * Returns true if the values are equivalent. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/eq/} */ $eq: [expression1: Expression, expression2: Expression]; @@ -1533,6 +1773,7 @@ export namespace Aggregation.Expression { export interface $exp { /** * Raises e to the specified exponent. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/exp/} */ $exp: ResolvesToNumber; @@ -1545,6 +1786,7 @@ export namespace Aggregation.Expression { export interface $filter { /** * Selects a subset of the array to return an array with only the elements that match the filter condition. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/filter/} */ $filter: { @@ -1560,6 +1802,12 @@ export namespace Aggregation.Expression { */ as?: string; + /** + * A name for the variable that represents the index of the current element in + * the input array. If specified, this variable is available within the cond expression. + */ + arrayIndexAs?: string; + /** * A number expression that restricts the number of matching array elements that $filter returns. You cannot specify a limit less than 1. The matching array elements are returned in the order they appear in the input array. * If the specified limit is greater than the number of matching array elements, $filter returns all matching array elements. If the limit is null, $filter returns all matching array elements. @@ -1575,6 +1823,7 @@ export namespace Aggregation.Expression { export interface $first { /** * Returns the result of an expression for the first document in an array. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/first/} */ $first: ResolvesToArray; @@ -1587,6 +1836,7 @@ export namespace Aggregation.Expression { export interface $firstN { /** * Returns a specified number of elements from the beginning of an array. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstN-array-element/} */ $firstN: { @@ -1609,6 +1859,7 @@ export namespace Aggregation.Expression { export interface $floor { /** * Returns the largest integer less than or equal to the specified number. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/floor/} */ $floor: ResolvesToNumber; @@ -1671,6 +1922,7 @@ export namespace Aggregation.Expression { export interface $gt { /** * Returns true if the first value is greater than the second. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/gt/} */ $gt: [expression1: Expression, expression2: Expression]; @@ -1683,11 +1935,48 @@ export namespace Aggregation.Expression { export interface $gte { /** * Returns true if the first value is greater than or equal to the second. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/gte/} */ $gte: [expression1: Expression, expression2: Expression]; } + /** + * A type describing the `$hash` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/} + */ + export interface $hash { + /** + * Generates and returns a binary hash value (BinData) from a UTF-8 string or binary data. Use $hash in an aggregation + * pipeline to compute binary hashes for storage, verification, or comparison. To get a hexadecimal string instead of + * binary data, use $hexHash. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/} + */ + $hash: { + input: ResolvesToString | ResolvesToBinData | ResolvesToNull; + algorithm: string; + }; + } + + /** + * A type describing the `$hexHash` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hexHash/} + */ + export interface $hexHash { + /** + * Generates and returns an uppercase hexadecimal string representation of a hash value from a UTF-8 string or binary + * data. Use $hexHash in an aggregation pipeline to compute hex-encoded hashes for storage, verification, or comparison. + * To get binary data instead of a hexadecimal string, use $hash. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hexHash/} + */ + $hexHash: { + input: ResolvesToString | ResolvesToBinData | ResolvesToNull; + algorithm: string; + }; + } + /** * A type describing the `$hour` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/} @@ -1695,6 +1984,7 @@ export namespace Aggregation.Expression { export interface $hour { /** * Returns the hour for a date as a number between 0 and 23. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hour/} */ $hour: { @@ -1717,6 +2007,7 @@ export namespace Aggregation.Expression { export interface $ifNull { /** * Returns either the non-null result of the first expression or the result of the second expression if the first expression results in a null result. Null result encompasses instances of undefined values or missing fields. Accepts two expressions as arguments. The result of the second expression can be null. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/ifNull/} */ $ifNull: [...Expression[]]; @@ -1729,6 +2020,7 @@ export namespace Aggregation.Expression { export interface $in { /** * Returns a boolean indicating whether a specified value is in an array. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/in/} */ $in: [ @@ -1751,6 +2043,7 @@ export namespace Aggregation.Expression { export interface $indexOfArray { /** * Searches an array for an occurrence of a specified value and returns the array index of the first occurrence. Array indexes start at zero. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfArray/} */ $indexOfArray: [ @@ -1783,6 +2076,7 @@ export namespace Aggregation.Expression { export interface $indexOfBytes { /** * Searches a string for an occurrence of a substring and returns the UTF-8 byte index of the first occurrence. If the substring is not found, returns -1. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfBytes/} */ $indexOfBytes: [ @@ -1819,6 +2113,7 @@ export namespace Aggregation.Expression { export interface $indexOfCP { /** * Searches a string for an occurrence of a substring and returns the UTF-8 code point index of the first occurrence. If the substring is not found, returns -1 + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexOfCP/} */ $indexOfCP: [ @@ -1855,6 +2150,7 @@ export namespace Aggregation.Expression { export interface $isArray { /** * Determines if the operand is an array. Returns a boolean. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/isArray/} */ $isArray: [expression: Expression]; @@ -1881,6 +2177,7 @@ export namespace Aggregation.Expression { export interface $isoDayOfWeek { /** * Returns the weekday number in ISO 8601 format, ranging from 1 (for Monday) to 7 (for Sunday). + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoDayOfWeek/} */ $isoDayOfWeek: { @@ -1903,6 +2200,7 @@ export namespace Aggregation.Expression { export interface $isoWeek { /** * Returns the week number in ISO 8601 format, ranging from 1 to 53. Week numbers start at 1 with the week (Monday through Sunday) that contains the year's first Thursday. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeek/} */ $isoWeek: { @@ -1925,6 +2223,7 @@ export namespace Aggregation.Expression { export interface $isoWeekYear { /** * Returns the year number in ISO 8601 format. The year starts with the Monday of week 1 (ISO 8601) and ends with the Sunday of the last week (ISO 8601). + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/isoWeekYear/} */ $isoWeekYear: { @@ -1947,6 +2246,7 @@ export namespace Aggregation.Expression { export interface $last { /** * Returns the result of an expression for the last document in an array. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/last/} */ $last: ResolvesToArray; @@ -1959,6 +2259,7 @@ export namespace Aggregation.Expression { export interface $lastN { /** * Returns a specified number of elements from the end of an array. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastN/#array-operator} */ $lastN: { @@ -1982,6 +2283,7 @@ export namespace Aggregation.Expression { /** * Defines variables for use within the scope of a subexpression and returns the result of the subexpression. Accepts named parameters. * Accepts any number of argument expressions. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/let/} */ $let: { @@ -2005,6 +2307,7 @@ export namespace Aggregation.Expression { export interface $literal { /** * Return a value without parsing. Use for values that the aggregation pipeline may interpret as an expression. For example, use a $literal expression to a string that starts with a dollar sign ($) to avoid parsing as a field path. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/literal/} */ $literal: any; @@ -2018,6 +2321,7 @@ export namespace Aggregation.Expression { /** * Calculates the natural log of a number. * $ln is equivalent to $log: [ , Math.E ] expression, where Math.E is a JavaScript representation for Euler's number e. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/ln/} */ $ln: ResolvesToNumber; @@ -2030,6 +2334,7 @@ export namespace Aggregation.Expression { export interface $log { /** * Calculates the log of a number in the specified base. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/log/} */ $log: [ @@ -2052,6 +2357,7 @@ export namespace Aggregation.Expression { export interface $log10 { /** * Calculates the log base 10 of a number. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/log10/} */ $log10: ResolvesToNumber; @@ -2064,6 +2370,7 @@ export namespace Aggregation.Expression { export interface $lt { /** * Returns true if the first value is less than the second. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lt/} */ $lt: [expression1: Expression, expression2: Expression]; @@ -2076,6 +2383,7 @@ export namespace Aggregation.Expression { export interface $lte { /** * Returns true if the first value is less than or equal to the second. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lte/} */ $lte: [expression1: Expression, expression2: Expression]; @@ -2113,6 +2421,7 @@ export namespace Aggregation.Expression { export interface $map { /** * Applies a subexpression to each element of an array and returns the array of resulting values in order. Accepts named parameters. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/map/} */ $map: { @@ -2124,7 +2433,13 @@ export namespace Aggregation.Expression { /** * A name for the variable that represents each individual element of the input array. If no name is specified, the variable name defaults to this. */ - as?: ResolvesToString; + as?: string; + + /** + * A name for the variable that represents the index of the current element in + * the input array. If specified, this variable is available within the in expression. + */ + arrayIndexAs?: string; /** * An expression that is applied to each element of the input array. The expression references each element individually with the variable name specified in as. @@ -2141,6 +2456,7 @@ export namespace Aggregation.Expression { /** * Returns the maximum value that results from applying an expression to each document. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/max/} */ $max: [...Expression[]]; @@ -2153,6 +2469,7 @@ export namespace Aggregation.Expression { export interface $maxN { /** * Returns the n largest values in an array. Distinct from the $maxN accumulator. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxN-array-element/} */ $maxN: { @@ -2175,18 +2492,18 @@ export namespace Aggregation.Expression { export interface $median { /** * Returns an approximation of the median, the 50th percentile, as a scalar value. - * New in MongoDB 7.0. * This operator is available as an accumulator in these stages: * $group * $setWindowFields * It is also available as an aggregation expression. + * New in MongoDB 7.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/median/} */ $median: { /** * $median calculates the 50th percentile value of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $median calculation ignores it. */ - input: ResolvesToNumber | ResolvesToNumber[]; + input: ResolvesToNumber | unknown[]; /** * The method that mongod uses to calculate the 50th percentile value. The method must be 'approximate'. @@ -2202,6 +2519,7 @@ export namespace Aggregation.Expression { export interface $mergeObjects { /** * Combines multiple documents into a single document. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/mergeObjects/} */ $mergeObjects: [ @@ -2219,6 +2537,7 @@ export namespace Aggregation.Expression { export interface $meta { /** * Access available per-document metadata related to the aggregation operation. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/meta/} */ $meta: string; @@ -2231,6 +2550,7 @@ export namespace Aggregation.Expression { export interface $millisecond { /** * Returns the milliseconds of a date as a number between 0 and 999. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/millisecond/} */ $millisecond: { @@ -2254,6 +2574,7 @@ export namespace Aggregation.Expression { /** * Returns the minimum value that results from applying an expression to each document. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/min/} */ $min: [...Expression[]]; @@ -2266,6 +2587,7 @@ export namespace Aggregation.Expression { export interface $minN { /** * Returns the n smallest values in an array. Distinct from the $minN accumulator. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minN-array-element/} */ $minN: { @@ -2288,6 +2610,7 @@ export namespace Aggregation.Expression { export interface $minute { /** * Returns the minute for a date as a number between 0 and 59. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minute/} */ $minute: { @@ -2310,6 +2633,7 @@ export namespace Aggregation.Expression { export interface $mod { /** * Returns the remainder of the first number divided by the second. Accepts two argument expressions. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/mod/} */ $mod: [ @@ -2328,6 +2652,7 @@ export namespace Aggregation.Expression { export interface $month { /** * Returns the month for a date as a number between 1 (January) and 12 (December). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/month/} */ $month: { @@ -2350,6 +2675,7 @@ export namespace Aggregation.Expression { export interface $multiply { /** * Multiplies numbers to return the product. Accepts any number of argument expressions. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/multiply/} */ $multiply: [ @@ -2368,6 +2694,7 @@ export namespace Aggregation.Expression { export interface $ne { /** * Returns true if the values are not equivalent. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/ne/} */ $ne: [expression1: Expression, expression2: Expression]; @@ -2380,6 +2707,7 @@ export namespace Aggregation.Expression { export interface $not { /** * Returns the boolean value that is the opposite of its argument expression. Accepts a single argument expression. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/not/} */ $not: [expression: Expression | ResolvesToBool]; @@ -2392,6 +2720,7 @@ export namespace Aggregation.Expression { export interface $objectToArray { /** * Converts a document to an array of documents representing key-value pairs. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/objectToArray/} */ $objectToArray: ResolvesToObject; @@ -2404,6 +2733,7 @@ export namespace Aggregation.Expression { export interface $or { /** * Returns true when any of its expressions evaluates to true. Accepts any number of argument expressions. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/or/} */ $or: [...(Expression | ResolvesToBool)[]]; @@ -2416,18 +2746,18 @@ export namespace Aggregation.Expression { export interface $percentile { /** * Returns an array of scalar values that correspond to specified percentile values. - * New in MongoDB 7.0. * This operator is available as an accumulator in these stages: * $group * $setWindowFields * It is also available as an aggregation expression. + * New in MongoDB 7.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile/} */ $percentile: { /** * $percentile calculates the percentile values of this data. input must be a field name or an expression that evaluates to a numeric type. If the expression cannot be converted to a numeric type, the $percentile calculation ignores it. */ - input: ResolvesToNumber | ResolvesToNumber[]; + input: ResolvesToNumber | unknown[]; /** * $percentile calculates a percentile value for each element in p. The elements represent percentages and must evaluate to numeric values in the range 0.0 to 1.0, inclusive. @@ -2449,6 +2779,7 @@ export namespace Aggregation.Expression { export interface $pow { /** * Raises a number to the specified exponent. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/pow/} */ $pow: [number: ResolvesToNumber, exponent: ResolvesToNumber]; @@ -2461,6 +2792,7 @@ export namespace Aggregation.Expression { export interface $radiansToDegrees { /** * Converts a value from radians to degrees. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/radiansToDegrees/} */ $radiansToDegrees: ResolvesToNumber; @@ -2473,6 +2805,7 @@ export namespace Aggregation.Expression { export interface $rand { /** * Returns a random float between 0 and 1 + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/rand/} */ $rand: Record; @@ -2485,6 +2818,7 @@ export namespace Aggregation.Expression { export interface $range { /** * Outputs an array containing a sequence of integers according to user-defined inputs. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/range/} */ $range: [ @@ -2512,6 +2846,7 @@ export namespace Aggregation.Expression { export interface $reduce { /** * Applies an expression to each element in an array and combines them into a single value. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/reduce/} */ $reduce: { @@ -2527,6 +2862,24 @@ export namespace Aggregation.Expression { */ initialValue: Expression; + /** + * A name for the variable that represents each individual element of the input array. + * If no name is specified, the variable name defaults to this. + */ + as?: string; + + /** + * A name for the variable that represents the cumulative value of the expression. + * If no name is specified, the variable name defaults to value. + */ + valueAs?: string; + + /** + * A name for the variable that represents the index of the current element in + * the input array. If specified, this variable is available within the in expression. + */ + arrayIndexAs?: string; + /** * A valid expression that $reduce applies to each element in the input array in left-to-right order. Wrap the input value with $reverseArray to yield the equivalent of applying the combining expression from right-to-left. * During evaluation of the in expression, two variables will be available: @@ -2537,12 +2890,12 @@ export namespace Aggregation.Expression { | Expression< S & { /** - * The variable that represents the cumulative value of the expression. + * The variable that refers to the element being processed. */ $this: any; /** - * The variable that refers to the element being processed. + * The variable that represents the cumulative value of the expression. */ $value: any; } @@ -2550,12 +2903,12 @@ export namespace Aggregation.Expression { | ExpressionMap< S & { /** - * The variable that represents the cumulative value of the expression. + * The variable that refers to the element being processed. */ $this: any; /** - * The variable that refers to the element being processed. + * The variable that represents the cumulative value of the expression. */ $value: any; } @@ -2655,7 +3008,7 @@ export namespace Aggregation.Expression { /** * The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. */ - find: ResolvesToString | ResolvesToNull; + find: ResolvesToString | ResolvesToNull | ResolvesToRegex; /** * The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. @@ -2676,17 +3029,17 @@ export namespace Aggregation.Expression { */ $replaceOne: { /** - * The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceAll returns null. + * The string on which you wish to apply the find. Can be any valid expression that resolves to a string or a null. If input refers to a field that is missing, $replaceOne returns null. */ input: ResolvesToString | ResolvesToNull; /** - * The string to search for within the given input. Can be any valid expression that resolves to a string or a null. If find refers to a field that is missing, $replaceAll returns null. + * The string or regex to search for within the given input. Can be any valid expression that resolves to a string, a regex, or a null. If find refers to a field that is missing, $replaceOne returns null. */ - find: ResolvesToString | ResolvesToNull; + find: ResolvesToString | ResolvesToNull | ResolvesToRegex; /** - * The string to use to replace all matched instances of find in input. Can be any valid expression that resolves to a string or a null. + * The string to use to replace the first matched instance of find in input. Can be any valid expression that resolves to a string or a null. */ replacement: ResolvesToString | ResolvesToNull; }; @@ -2699,6 +3052,7 @@ export namespace Aggregation.Expression { export interface $reverseArray { /** * Returns an array with the elements in reverse order. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/reverseArray/} */ $reverseArray: ResolvesToArray; @@ -2711,6 +3065,7 @@ export namespace Aggregation.Expression { export interface $round { /** * Rounds a number to a whole integer or to a specified decimal place. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/round/} */ $round: [ @@ -2734,6 +3089,7 @@ export namespace Aggregation.Expression { export interface $rtrim { /** * Removes whitespace characters, including null, or the specified characters from the end of a string. + * New in MongoDB 4.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/rtrim/} */ $rtrim: { @@ -2758,6 +3114,7 @@ export namespace Aggregation.Expression { export interface $second { /** * Returns the seconds for a date as a number between 0 and 60 (leap seconds). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/second/} */ $second: { @@ -2773,6 +3130,40 @@ export namespace Aggregation.Expression { }; } + /** + * A type describing the `$serializeEJSON` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/} + */ + export interface $serializeEJSON { + /** + * Converts BSON values to Extended JSON (EJSON) format. The result is a + * BSON document with EJSON type wrappers that can then be converted to + * a JSON string using $toString. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/} + */ + $serializeEJSON: { + /** + * The BSON value to convert to Extended JSON format. + */ + input: Expression; + + /** + * Specifies whether to use Relaxed Extended JSON format. If true, numeric types + * (Int32, Int64, Double) are represented as native JSON numbers for better readability. + * If false or unspecified, uses Canonical Extended JSON format which preserves type + * information for all BSON types. Defaults to false. + */ + relaxed?: ResolvesToBool; + + /** + * The value to return if the operation encounters an error during conversion. + * If unspecified, the operation throws an error and stops. + */ + onError?: Expression; + }; + } + /** * A type describing the `$setDifference` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setDifference/} @@ -2780,6 +3171,7 @@ export namespace Aggregation.Expression { export interface $setDifference { /** * Returns a set with elements that appear in the first set but not in the second set; i.e. performs a relative complement of the second set relative to the first. Accepts exactly two argument expressions. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setDifference/} */ $setDifference: [ @@ -2802,6 +3194,7 @@ export namespace Aggregation.Expression { export interface $setEquals { /** * Returns true if the input sets have the same distinct elements. Accepts two or more argument expressions. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setEquals/} */ $setEquals: [...ResolvesToArray[]]; @@ -2843,6 +3236,7 @@ export namespace Aggregation.Expression { export interface $setIntersection { /** * Returns a set with elements that appear in all of the input sets. Accepts any number of argument expressions. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIntersection/} */ $setIntersection: [...ResolvesToArray[]]; @@ -2855,6 +3249,7 @@ export namespace Aggregation.Expression { export interface $setIsSubset { /** * Returns true if all elements of the first set appear in the second set, including when the first set equals the second set; i.e. not a strict subset. Accepts exactly two argument expressions. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setIsSubset/} */ $setIsSubset: [ @@ -2870,47 +3265,139 @@ export namespace Aggregation.Expression { export interface $setUnion { /** * Returns a set with elements that appear in any of the input sets. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/} */ $setUnion: [...ResolvesToArray[]]; } /** - * A type describing the `$sin` operator. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/} + * A type describing the `$sigmoid` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sigmoid/} */ - export interface $sin { + export interface $sigmoid { /** - * Returns the sine of a value that is measured in radians. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/} + * Returns the sigmoid of a value, defined as 1 / (1 + e^(-x)). The result is a value between 0 and 1. + * New in MongoDB 8.1. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sigmoid/} */ - $sin: ResolvesToNumber; + $sigmoid: ResolvesToNumber; } /** - * A type describing the `$sinh` operator. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/} + * A type describing the `$similarityCosine` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityCosine/} */ - export interface $sinh { + export interface $similarityCosine { /** - * Returns the hyperbolic sine of a value that is measured in radians. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/} + * Returns the cosine similarity between two vectors. If the score argument is true, the result + * is normalized to a value between 0 and 1 for use as a vector search score. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityCosine/} */ - $sinh: ResolvesToNumber; + $similarityCosine: { + /** + * An array of exactly two expressions that each resolve to an array of numbers. + * Both arrays must have the same length. + */ + vectors: ResolvesToArray; + + /** + * If true, normalizes the result to a value between 0 and 1 for use as a vector search score. Defaults to false. + */ + score?: boolean; + }; } /** - * A type describing the `$size` operator. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/} + * A type describing the `$similarityDotProduct` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityDotProduct/} */ - export interface $size { + export interface $similarityDotProduct { /** - * Returns the number of elements in the array. Accepts a single expression as argument. - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/} + * Returns the dot product similarity between two vectors. If the score argument is true, the result + * is normalized to a value between 0 and 1 for use as a vector search score. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityDotProduct/} */ - $size: ResolvesToArray; - } - + $similarityDotProduct: { + /** + * An array of exactly two expressions that each resolve to an array of numbers. + * Both arrays must have the same length. + */ + vectors: ResolvesToArray; + + /** + * If true, normalizes the result to a value between 0 and 1 for use as a vector search score. Defaults to false. + */ + score?: boolean; + }; + } + + /** + * A type describing the `$similarityEuclidean` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityEuclidean/} + */ + export interface $similarityEuclidean { + /** + * Returns the Euclidean similarity between two vectors. If the score argument is true, the result + * is normalized to a value between 0 and 1 for use as a vector search score. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityEuclidean/} + */ + $similarityEuclidean: { + /** + * An array of exactly two expressions that each resolve to an array of numbers. + * Both arrays must have the same length. + */ + vectors: ResolvesToArray; + + /** + * If true, normalizes the result to a value between 0 and 1 for use as a vector search score. Defaults to false. + */ + score?: boolean; + }; + } + + /** + * A type describing the `$sin` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/} + */ + export interface $sin { + /** + * Returns the sine of a value that is measured in radians. + * New in MongoDB 4.2. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sin/} + */ + $sin: ResolvesToNumber; + } + + /** + * A type describing the `$sinh` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/} + */ + export interface $sinh { + /** + * Returns the hyperbolic sine of a value that is measured in radians. + * New in MongoDB 4.2. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sinh/} + */ + $sinh: ResolvesToNumber; + } + + /** + * A type describing the `$size` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/} + */ + export interface $size { + /** + * Returns the number of elements in the array. Accepts a single expression as argument. + * New in MongoDB 3.2. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/size/} + */ + $size: ResolvesToArray; + } + /** * A type describing the `$slice` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/slice/} @@ -2918,6 +3405,7 @@ export namespace Aggregation.Expression { export interface $slice { /** * Returns a subset of an array. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/slice/} */ $slice: @@ -2963,6 +3451,7 @@ export namespace Aggregation.Expression { export interface $sortArray { /** * Sorts the elements of an array. + * New in MongoDB 5.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortArray/} */ $sortArray: { @@ -2987,6 +3476,7 @@ export namespace Aggregation.Expression { export interface $split { /** * Splits a string into substrings based on a delimiter. Returns an array of substrings. If the delimiter is not found within the string, returns an array containing the original string. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/split/} */ $split: [ @@ -2996,9 +3486,9 @@ export namespace Aggregation.Expression { string: ResolvesToString, /** - * The delimiter to use when splitting the string expression. delimiter can be any valid expression as long as it resolves to a string. + * The delimiter to use when splitting the string expression. delimiter can be any valid expression as long as it resolves to a string or a regular expression. */ - delimiter: ResolvesToString, + delimiter: ResolvesToString | ResolvesToRegex, ]; } @@ -3009,6 +3499,7 @@ export namespace Aggregation.Expression { export interface $sqrt { /** * Calculates the square root. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sqrt/} */ $sqrt: ResolvesToNumber; @@ -3023,6 +3514,7 @@ export namespace Aggregation.Expression { * Calculates the population standard deviation of the input values. Use if the values encompass the entire population of data you want to represent and do not wish to generalize about a larger population. $stdDevPop ignores non-numeric values. * If the values represent only a sample of a population of data from which to generalize about the population, use $stdDevSamp instead. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevPop/} */ $stdDevPop: [...ResolvesToNumber[]]; @@ -3036,6 +3528,7 @@ export namespace Aggregation.Expression { /** * Calculates the sample standard deviation of the input values. Use if the values encompass a sample of a population of data from which to generalize about the population. $stdDevSamp ignores non-numeric values. * If the values represent the entire population of data or you do not wish to generalize about a larger population, use $stdDevPop instead. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/stdDevSamp/} */ $stdDevSamp: [...ResolvesToNumber[]]; @@ -3048,6 +3541,7 @@ export namespace Aggregation.Expression { export interface $strLenBytes { /** * Returns the number of UTF-8 encoded bytes in a string. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenBytes/} */ $strLenBytes: ResolvesToString; @@ -3060,6 +3554,7 @@ export namespace Aggregation.Expression { export interface $strLenCP { /** * Returns the number of UTF-8 code points in a string. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/strLenCP/} */ $strLenCP: ResolvesToString; @@ -3072,6 +3567,7 @@ export namespace Aggregation.Expression { export interface $strcasecmp { /** * Performs case-insensitive string comparison and returns: 0 if two strings are equivalent, 1 if the first string is greater than the second, and -1 if the first string is less than the second. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/strcasecmp/} */ $strcasecmp: [ @@ -3087,6 +3583,7 @@ export namespace Aggregation.Expression { export interface $substr { /** * Deprecated. Use $substrBytes or $substrCP. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/substr/} */ $substr: [ @@ -3111,6 +3608,7 @@ export namespace Aggregation.Expression { export interface $substrBytes { /** * Returns the substring of a string. Starts with the character at the specified UTF-8 byte index (zero-based) in the string and continues for the specified number of bytes. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrBytes/} */ $substrBytes: [ @@ -3135,6 +3633,7 @@ export namespace Aggregation.Expression { export interface $substrCP { /** * Returns the substring of a string. Starts with the character at the specified UTF-8 code point (CP) index (zero-based) in the string and continues for the number of code points specified. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/substrCP/} */ $substrCP: [ @@ -3159,6 +3658,7 @@ export namespace Aggregation.Expression { export interface $subtract { /** * Returns the result of subtracting the second value from the first. If the two values are numbers, return the difference. If the two values are dates, return the difference in milliseconds. If the two values are a date and a number in milliseconds, return the resulting date. Accepts two argument expressions. If the two values are a date and a number, specify the date argument first as it is not meaningful to subtract a date from a number. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtract/} */ $subtract: [ @@ -3167,6 +3667,20 @@ export namespace Aggregation.Expression { ]; } + /** + * A type describing the `$subtype` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtype/} + */ + export interface $subtype { + /** + * Returns the subtype of a given value as an integer. In MongoDB 8.3, the only expression + * that contains a subtype is a BinData expression. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtype/} + */ + $subtype: ResolvesToBinData; + } + /** * A type describing the `$sum` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/} @@ -3175,6 +3689,7 @@ export namespace Aggregation.Expression { /** * Returns a sum of numerical values. Ignores non-numeric values. * Changed in MongoDB 5.0: Available in the $setWindowFields stage. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum/} */ $sum: [...(ResolvesToNumber | ResolvesToArray)[]]; @@ -3187,6 +3702,7 @@ export namespace Aggregation.Expression { export interface $switch { /** * Evaluates a series of case expressions. When it finds an expression which evaluates to true, $switch executes a specified expression and breaks out of the control flow. + * New in MongoDB 4.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/switch/} */ $switch: { @@ -3213,6 +3729,7 @@ export namespace Aggregation.Expression { export interface $tan { /** * Returns the tangent of a value that is measured in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/tan/} */ $tan: ResolvesToNumber; @@ -3225,11 +3742,26 @@ export namespace Aggregation.Expression { export interface $tanh { /** * Returns the hyperbolic tangent of a value that is measured in radians. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/tanh/} */ $tanh: ResolvesToNumber; } + /** + * A type describing the `$toArray` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toArray/} + */ + export interface $toArray { + /** + * Converts a value to an array. If the value cannot be converted, $toArray errors. + * If the value is null or missing, $toArray returns null. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toArray/} + */ + $toArray: Expression; + } + /** * A type describing the `$toBool` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toBool/} @@ -3289,6 +3821,7 @@ export namespace Aggregation.Expression { export interface $toHashedIndexKey { /** * Computes and returns the hash value of the input expression using the same hash function that MongoDB uses to create a hashed index. A hash function maps a key or string to a fixed-size numeric value. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toHashedIndexKey/} */ $toHashedIndexKey: Expression; @@ -3327,11 +3860,26 @@ export namespace Aggregation.Expression { export interface $toLower { /** * Converts a string to lowercase. Accepts a single argument expression. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toLower/} */ $toLower: ResolvesToString; } + /** + * A type describing the `$toObject` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObject/} + */ + export interface $toObject { + /** + * Converts a string to an object. If the value cannot be converted, $toObject errors. + * If the value is null or missing, $toObject returns null. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObject/} + */ + $toObject: Expression; + } + /** * A type describing the `$toObjectId` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObjectId/} @@ -3365,11 +3913,74 @@ export namespace Aggregation.Expression { export interface $toUpper { /** * Converts a string to uppercase. Accepts a single argument expression. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toUpper/} */ $toUpper: ResolvesToString; } + /** + * A type describing the `$top` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/top-array-operator/} + */ + export interface $top { + /** + * Returns the top element within an array according to the specified sort order. + * New in MongoDB 7.0. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/top-array-operator/} + */ + $top: { + /** + * Specifies the order of results, with syntax similar to $sort. + */ + sortBy: SortBy; + + /** + * Represents the output for each element in the input array and can be any expression. + */ + output: Expression; + + /** + * An expression that resolves to the array from which to return the top element. + */ + input: ResolvesToArray; + }; + } + + /** + * A type describing the `$topN` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN-array-operator/} + */ + export interface $topN { + /** + * Returns an aggregation of the top n elements within an array, according to the specified sort order. + * If the array contains fewer than n elements, $topN returns all elements in the array. + * New in MongoDB 7.0. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN-array-operator/} + */ + $topN: { + /** + * An expression that resolves to a positive integer. The integer specifies the number of array elements that $topN returns. + */ + n: ResolvesToInt; + + /** + * Specifies the order of results, with syntax similar to $sort. + */ + sortBy: SortBy; + + /** + * Represents the output for each element in the input array and can be any expression. + */ + output: Expression; + + /** + * An expression that resolves to the array from which to return the top n elements. + */ + input: ResolvesToArray; + }; + } + /** * A type describing the `$trim` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/trim/} @@ -3402,6 +4013,7 @@ export namespace Aggregation.Expression { export interface $trunc { /** * Truncates a number to a whole integer or to a specified decimal place. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/trunc/} */ $trunc: [ @@ -3451,6 +4063,7 @@ export namespace Aggregation.Expression { export interface $type { /** * Return the BSON data type of the field. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/type/} */ $type: Expression; @@ -3464,6 +4077,7 @@ export namespace Aggregation.Expression { /** * You can use $unsetField to remove fields with names that contain periods (.) or that start with dollar signs ($). * $unsetField is an alias for $setField using $$REMOVE to remove fields. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/unsetField/} */ $unsetField: { @@ -3486,6 +4100,7 @@ export namespace Aggregation.Expression { export interface $week { /** * Returns the week number for a date as a number between 0 (the partial week that precedes the first Sunday of the year) and 53 (leap year). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/week/} */ $week: { @@ -3508,6 +4123,7 @@ export namespace Aggregation.Expression { export interface $year { /** * Returns the year for a date as a number (e.g. 2014). + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/year/} */ $year: { @@ -3530,6 +4146,7 @@ export namespace Aggregation.Expression { export interface $zip { /** * Merge two arrays together. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/zip/} */ $zip: { @@ -3563,6 +4180,7 @@ export namespace Aggregation.Query { export interface $all { /** * Matches arrays that contain all elements specified in the query. + * New in MongoDB 2.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/all/} */ $all: [...FieldQuery[]]; @@ -3587,9 +4205,10 @@ export namespace Aggregation.Query { export interface $bitsAllClear { /** * Matches numeric or binary values in which a set of bit positions all have a value of 0. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/bitsAllClear/} */ - $bitsAllClear: (Int | bson.Binary) | (Int | bson.Binary)[]; + $bitsAllClear: (Int | bson.Binary) | unknown[]; } /** @@ -3599,9 +4218,10 @@ export namespace Aggregation.Query { export interface $bitsAllSet { /** * Matches numeric or binary values in which a set of bit positions all have a value of 1. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/bitsAllSet/} */ - $bitsAllSet: (Int | bson.Binary) | (Int | bson.Binary)[]; + $bitsAllSet: (Int | bson.Binary) | unknown[]; } /** @@ -3611,9 +4231,10 @@ export namespace Aggregation.Query { export interface $bitsAnyClear { /** * Matches numeric or binary values in which any bit from a set of bit positions has a value of 0. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/bitsAnyClear/} */ - $bitsAnyClear: (Int | bson.Binary) | (Int | bson.Binary)[]; + $bitsAnyClear: (Int | bson.Binary) | unknown[]; } /** @@ -3623,9 +4244,10 @@ export namespace Aggregation.Query { export interface $bitsAnySet { /** * Matches numeric or binary values in which any bit from a set of bit positions has a value of 1. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/bitsAnySet/} */ - $bitsAnySet: (Int | bson.Binary) | (Int | bson.Binary)[]; + $bitsAnySet: (Int | bson.Binary) | unknown[]; } /** @@ -3635,6 +4257,7 @@ export namespace Aggregation.Query { export interface $box { /** * Specifies a rectangular box using legacy coordinate pairs for $geoWithin queries. The 2d index supports $box. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/box/} */ $box: unknown[]; @@ -3647,6 +4270,7 @@ export namespace Aggregation.Query { export interface $center { /** * Specifies a circle using legacy coordinate pairs to $geoWithin queries when using planar geometry. The 2d index supports $center. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/center/} */ $center: unknown[]; @@ -3659,11 +4283,25 @@ export namespace Aggregation.Query { export interface $centerSphere { /** * Specifies a circle using either legacy coordinate pairs or GeoJSON format for $geoWithin queries when using spherical geometry. The 2dsphere and 2d indexes support $centerSphere. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/centerSphere/} */ $centerSphere: unknown[]; } + /** + * A type describing the `$comment` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/comment/} + */ + export interface $comment { + /** + * Adds a comment to a query predicate. + * New in MongoDB 2.6. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/comment/} + */ + $comment: string; + } + /** * A type describing the `$elemMatch` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch/} @@ -3671,6 +4309,7 @@ export namespace Aggregation.Query { export interface $elemMatch { /** * The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/elemMatch/} */ $elemMatch: Query | FieldQuery; @@ -3683,9 +4322,10 @@ export namespace Aggregation.Query { export interface $eq { /** * Matches values that are equal to a specified value. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/eq/} */ - $eq: Expression; + $eq: any; } /** @@ -3707,6 +4347,7 @@ export namespace Aggregation.Query { export interface $expr { /** * Allows use of aggregation expressions within the query language. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/expr/} */ $expr: Expression; @@ -3719,6 +4360,7 @@ export namespace Aggregation.Query { export interface $geoIntersects { /** * Selects geometries that intersect with a GeoJSON geometry. The 2dsphere index supports $geoIntersects. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/geoIntersects/} */ $geoIntersects: Geometry & {}; @@ -3731,6 +4373,7 @@ export namespace Aggregation.Query { export interface $geoWithin { /** * Selects geometries within a bounding GeoJSON geometry. The 2dsphere and 2d indexes support $geoWithin. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/geoWithin/} */ $geoWithin: Geometry & {}; @@ -3743,6 +4386,7 @@ export namespace Aggregation.Query { export interface $geometry { /** * Specifies a geometry in GeoJSON format to geospatial query operators. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/geometry/} */ $geometry: { @@ -3795,6 +4439,7 @@ export namespace Aggregation.Query { export interface $jsonSchema { /** * Validate documents against the given JSON Schema. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/jsonSchema/} */ $jsonSchema: Record; @@ -3831,6 +4476,7 @@ export namespace Aggregation.Query { export interface $maxDistance { /** * Specifies a maximum distance to limit the results of $near and $nearSphere queries. The 2dsphere and 2d indexes support $maxDistance. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/maxDistance/} */ $maxDistance: Number; @@ -3843,6 +4489,7 @@ export namespace Aggregation.Query { export interface $minDistance { /** * Specifies a minimum distance to limit the results of $near and $nearSphere queries. For use with 2dsphere index only. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/minDistance/} */ $minDistance: Int | Double; @@ -3879,6 +4526,7 @@ export namespace Aggregation.Query { export interface $near { /** * Returns geospatial objects in proximity to a point. Requires a geospatial index. The 2dsphere and 2d indexes support $near. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/near/} */ $near: Geometry & { @@ -3901,6 +4549,7 @@ export namespace Aggregation.Query { export interface $nearSphere { /** * Returns geospatial objects in proximity to a point on a sphere. Requires a geospatial index. The 2dsphere and 2d indexes support $nearSphere. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/nearSphere/} */ $nearSphere: Geometry & { @@ -3971,6 +4620,7 @@ export namespace Aggregation.Query { export interface $polygon { /** * Specifies a polygon to using legacy coordinate pairs for $geoWithin queries. The 2d index supports $center. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/polygon/} */ $polygon: unknown[]; @@ -3983,6 +4633,7 @@ export namespace Aggregation.Query { export interface $rand { /** * Generates a random float between 0 and 1. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/rand/} */ $rand: Record; @@ -4007,6 +4658,7 @@ export namespace Aggregation.Query { export interface $sampleRate { /** * Randomly select documents at a given rate. Although the exact number of documents selected varies on each run, the quantity chosen approximates the sample rate expressed as a percentage of the total number of documents. + * New in MongoDB 5.3. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sampleRate/} */ $sampleRate: ResolvesToDouble; @@ -4031,6 +4683,7 @@ export namespace Aggregation.Query { export interface $text { /** * Performs text search. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/} */ $text: { @@ -4065,6 +4718,7 @@ export namespace Aggregation.Query { export interface $type { /** * Selects documents if a field is of the specified type. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/type/} */ $type: [...(Int | string)[]]; @@ -4093,6 +4747,7 @@ export namespace Aggregation.Search { * contains a sequence of characters from an incomplete input string. The * fields that you intend to query with the autocomplete operator must be * indexed with the autocomplete data type in the collection's index definition. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/autocomplete/} */ autocomplete: { @@ -4113,15 +4768,17 @@ export namespace Aggregation.Search { * The compound operator combines two or more operators into a single query. * Each element of a compound query is called a clause, and each clause * consists of one or more sub-queries. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/compound/} */ compound: { - must?: SearchOperator | SearchOperator[]; - mustNot?: SearchOperator | SearchOperator[]; - should?: SearchOperator | SearchOperator[]; - filter?: SearchOperator | SearchOperator[]; + must?: SearchOperator | unknown[]; + mustNot?: SearchOperator | unknown[]; + should?: SearchOperator | unknown[]; + filter?: SearchOperator | unknown[]; minimumShouldMatch?: Int; score?: SearchScore; + doesNotAffect?: string | unknown[]; }; } @@ -4135,6 +4792,7 @@ export namespace Aggregation.Search { * It constrains multiple query predicates to be satisfied from a single * element of an array of embedded documents. embeddedDocument can be used only * for queries over fields of the embeddedDocuments + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/embedded-document/} */ embeddedDocument: { @@ -4151,6 +4809,7 @@ export namespace Aggregation.Search { export interface Equals { /** * The equals operator checks whether a field matches a value you specify. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/equals/} */ equals: { @@ -4164,6 +4823,7 @@ export namespace Aggregation.Search { | Number | string; score?: SearchScore; + doesNotAffect?: string | unknown[]; }; } @@ -4174,6 +4834,7 @@ export namespace Aggregation.Search { export interface Exists { /** * The exists operator tests if a path to a specified indexed field name exists in a document. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/exists/} */ exists: { path: SearchPath; score?: SearchScore }; @@ -4187,6 +4848,7 @@ export namespace Aggregation.Search { /** * The facet collector groups results by values or ranges in the specified * faceted fields and returns the count for each of those groups. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/facet/} */ facet: { facets: Record; operator?: SearchOperator }; @@ -4200,6 +4862,7 @@ export namespace Aggregation.Search { /** * The geoShape operator supports querying shapes with a relation to a given * geometry if indexShapes is set to true in the index definition. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/geoShape/} */ geoShape: { @@ -4219,6 +4882,7 @@ export namespace Aggregation.Search { * The geoWithin operator supports querying geographic points within a given * geometry. Only points are returned, even if indexShapes value is true in * the index definition. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/geoWithin/} */ geoWithin: { @@ -4230,6 +4894,32 @@ export namespace Aggregation.Search { }; } + /** + * A type describing the `hasAncestor` operator. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasancestor/} + */ + export interface HasAncestor { + /** + * The `hasAncestor` operator queries an `embeddedDocuments` type field specified in the `ancestorPath`. The `ancestorPath` is a parent of the field specified in the `returnScope`. + * New in MongoDB 8.2. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasancestor/} + */ + hasAncestor: { ancestorPath: SearchPath; operator: SearchOperator }; + } + + /** + * A type describing the `hasRoot` operator. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasroot/} + */ + export interface HasRoot { + /** + * The `hasRoot` operator can be used to query root-level fields when you specify the `returnScope` and `returnStoredSource` options. + * New in MongoDB 8.2. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasroot/} + */ + hasRoot: { operator: SearchOperator }; + } + /** * A type describing the `in` operator. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/in/} @@ -4237,9 +4927,15 @@ export namespace Aggregation.Search { export interface In { /** * The in operator performs a search for an array of BSON values in a field. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/in/} */ - in: { path: SearchPath; value: any | any[]; score?: SearchScore }; + in: { + path: SearchPath; + value: any | unknown[]; + score?: SearchScore; + doesNotAffect?: string | unknown[]; + }; } /** @@ -4251,10 +4947,11 @@ export namespace Aggregation.Search { * The moreLikeThis operator returns documents similar to input documents. * The moreLikeThis operator allows you to build features for your applications * that display similar or alternative results based on one or more given documents. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/moreLikeThis/} */ moreLikeThis: { - like: Record | Record[]; + like: Record | unknown[]; score?: SearchScore; }; } @@ -4266,6 +4963,7 @@ export namespace Aggregation.Search { export interface Near { /** * The near operator supports querying and scoring numeric, date, and GeoJSON point values. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/near/} */ near: { @@ -4283,11 +4981,12 @@ export namespace Aggregation.Search { export interface Phrase { /** * The phrase operator performs search for documents containing an ordered sequence of terms using the analyzer specified in the index configuration. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/phrase/} */ phrase: { path: SearchPath; - query: string | string[]; + query: string | unknown[]; slop?: Int; synonyms?: string; score?: SearchScore; @@ -4310,6 +5009,7 @@ export namespace Aggregation.Search { /** * The range operator supports querying and scoring numeric, date, and string values. * You can use this operator to find results that are within a given numeric, date, objectId, or letter (from the English alphabet) range. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/range/} */ range: { @@ -4319,6 +5019,7 @@ export namespace Aggregation.Search { lt?: Date | Number | string | bson.ObjectId; lte?: Date | Number | string | bson.ObjectId; score?: SearchScore; + doesNotAffect?: string | unknown[]; }; } @@ -4330,6 +5031,7 @@ export namespace Aggregation.Search { /** * regex interprets the query field as a regular expression. * regex is a term-level operator, meaning that the query field isn't analyzed. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/regex/} */ regex: { @@ -4348,6 +5050,7 @@ export namespace Aggregation.Search { /** * The text operator performs a full-text search using the analyzer that you specify in the index configuration. * If you omit an analyzer, the text operator uses the default standard analyzer. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/text/} */ text: { @@ -4360,6 +5063,61 @@ export namespace Aggregation.Search { }; } + /** + * A type describing the `vectorSearch` operator. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/vector-search/} + */ + export interface VectorSearch { + /** + * The vectorSearch operator performs an ANN or ENN search on a vector field. It can only be + * used as a top-level operator in a $search or $searchMeta query, not nested under compound + * or other operators. + * New in MongoDB 6.0. + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/vector-search/} + */ + vectorSearch: { + /** + * The indexed vector field to search. + */ + path: SearchPath; + + /** + * Array of numbers or a BinData value that represents the query vector. The number type + * must match the indexed field value type. + */ + queryVector: bson.Binary | unknown[]; + + /** + * The integer number of documents to return in the results. This value cannot exceed + * numCandidates if numCandidates is specified. + */ + limit: Int; + + /** + * If false, runs an ANN search. If true, runs an ENN search. Defaults to false. + * This parameter is required if numCandidates is omitted. + */ + exact?: boolean; + + /** + * The number of nearest neighbors to use during the search. Value must be less than or + * equal to 10000 and cannot be less than limit. This field is required if exact is false + * or omitted. + */ + numCandidates?: Int; + + /** + * Any Atlas Search operator to filter documents based on metadata or specific search criteria. + */ + filter?: SearchOperator; + + /** + * Score assigned to matching search results. + */ + score?: SearchScore; + }; + } + /** * A type describing the `wildcard` operator. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/wildcard/} @@ -4367,6 +5125,7 @@ export namespace Aggregation.Search { export interface Wildcard { /** * The wildcard operator enables queries which use special characters in the search string that can match any character. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/wildcard/} */ wildcard: { @@ -4385,6 +5144,7 @@ export namespace Aggregation.Stage { export interface $addFields { /** * Adds new fields to documents. Outputs documents that contain all existing fields from the input documents and newly added fields. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/} */ $addFields: { @@ -4401,6 +5161,7 @@ export namespace Aggregation.Stage { export interface $bucket { /** * Categorizes incoming documents into groups, called buckets, based on a specified expression and bucket boundaries. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucket/} */ $bucket: { @@ -4440,6 +5201,7 @@ export namespace Aggregation.Stage { export interface $bucketAuto { /** * Categorizes incoming documents into a specific number of groups, called buckets, based on a specified expression. Bucket boundaries are automatically determined in an attempt to evenly distribute the documents into the specified number of buckets. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bucketAuto/} */ $bucketAuto: { @@ -4474,6 +5236,7 @@ export namespace Aggregation.Stage { export interface $changeStream { /** * Returns a Change Stream cursor for the collection or database. This stage can only occur once in an aggregation pipeline and it must occur as the first stage. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/changeStream/} */ $changeStream: { @@ -4499,7 +5262,6 @@ export namespace Aggregation.Stage { /** * Specifies whether to include additional change events, such as such as DDL and index operations. - * New in MongoDB 6.0. */ showExpandedEvents?: boolean; @@ -4523,6 +5285,7 @@ export namespace Aggregation.Stage { /** * Splits large change stream events that exceed 16 MB into smaller fragments returned in a change stream cursor. * You can only use $changeStreamSplitLargeEvent in a $changeStream pipeline and it must be the final stage in the pipeline. + * New in MongoDB 6.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/changeStreamSplitLargeEvent/} */ $changeStreamSplitLargeEvent: Record; @@ -4535,6 +5298,7 @@ export namespace Aggregation.Stage { export interface $collStats { /** * Returns statistics regarding a collection or view. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/collStats/} */ $collStats: { @@ -4553,6 +5317,7 @@ export namespace Aggregation.Stage { /** * Returns a count of the number of documents at this stage of the aggregation pipeline. * Distinct from the $count aggregation accumulator. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/count/} */ $count: string; @@ -4565,6 +5330,7 @@ export namespace Aggregation.Stage { export interface $currentOp { /** * Returns information on active and/or dormant operations for the MongoDB deployment. To run, use the db.aggregate() method. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/currentOp/} */ $currentOp: { @@ -4583,6 +5349,7 @@ export namespace Aggregation.Stage { export interface $densify { /** * Creates new documents in a sequence of documents where certain values in a field are missing. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/} */ $densify: { @@ -4612,6 +5379,7 @@ export namespace Aggregation.Stage { export interface $documents { /** * Returns literal documents from input values. + * New in MongoDB 5.1. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents/} */ $documents: ResolvesToArray; @@ -4624,6 +5392,7 @@ export namespace Aggregation.Stage { export interface $facet { /** * Processes multiple aggregation pipelines within a single stage on the same set of input documents. Enables the creation of multi-faceted aggregations capable of characterizing data across multiple dimensions, or facets, in a single stage. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/} */ $facet: {} & { [facet: string]: Pipeline }; @@ -4636,6 +5405,7 @@ export namespace Aggregation.Stage { export interface $fill { /** * Populates null and missing field values within documents. + * New in MongoDB 5.3. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/fill/} */ $fill: { @@ -4673,6 +5443,7 @@ export namespace Aggregation.Stage { export interface $geoNear { /** * Returns an ordered stream of documents based on the proximity to a geospatial point. Incorporates the functionality of $match, $sort, and $limit for geospatial data. The output documents include an additional distance field and can include a location identifier field. + * New in MongoDB 2.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/} */ $geoNear: { @@ -4736,6 +5507,7 @@ export namespace Aggregation.Stage { export interface $graphLookup { /** * Performs a recursive search on a collection. To each output document, adds a new array field that contains the traversal results of the recursive search for that document. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/graphLookup/} */ $graphLookup: { @@ -4748,7 +5520,7 @@ export namespace Aggregation.Stage { /** * Expression that specifies the value of the connectFromField with which to start the recursive search. Optionally, startWith may be array of values, each of which is individually followed through the traversal process. */ - startWith: Expression | Expression[]; + startWith: Expression | unknown[]; /** * Field name whose value $graphLookup uses to recursively match against the connectToField of other documents in the collection. If the value is an array, each element is individually followed through the traversal process. @@ -4789,6 +5561,7 @@ export namespace Aggregation.Stage { export interface $group { /** * Groups input documents by a specified identifier expression and applies the accumulator expression(s), if specified, to each group. Consumes all input documents and outputs one document per each distinct group. The output documents only contain the identifier field and, if specified, accumulated fields. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/} */ $group: RecordWithStaticFields< @@ -4796,7 +5569,7 @@ export namespace Aggregation.Stage { /** * The _id expression specifies the group key. If you specify an _id value of null, or any other constant value, the $group stage returns a single document that aggregates values across all of the input documents. */ - _id: Expression | ExpressionMap; + _id: Expression; }, /** * Computed using the accumulator operators. @@ -4812,6 +5585,7 @@ export namespace Aggregation.Stage { export interface $indexStats { /** * Returns statistics regarding the use of each index for the collection. + * New in MongoDB 3.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexStats/} */ $indexStats: Record; @@ -4824,6 +5598,7 @@ export namespace Aggregation.Stage { export interface $limit { /** * Passes the first n documents unmodified to the pipeline where n is the specified limit. For each input document, outputs either one document (for the first n documents) or zero documents (after the first n documents). + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit/} */ $limit: Int; @@ -4836,6 +5611,7 @@ export namespace Aggregation.Stage { export interface $listLocalSessions { /** * Lists all active sessions recently in use on the currently connected mongos or mongod instance. These sessions may have not yet propagated to the system.sessions collection. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/listLocalSessions/} */ $listLocalSessions: { @@ -4858,6 +5634,7 @@ export namespace Aggregation.Stage { export interface $listSampledQueries { /** * Lists sampled queries for all collections or a specific collection. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSampledQueries/} */ $listSampledQueries: { namespace?: string }; @@ -4870,6 +5647,7 @@ export namespace Aggregation.Stage { export interface $listSearchIndexes { /** * Returns information about existing Atlas Search indexes on a specified collection. + * New in MongoDB 7.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSearchIndexes/} */ $listSearchIndexes: { @@ -4892,6 +5670,7 @@ export namespace Aggregation.Stage { export interface $listSessions { /** * Lists all sessions that have been active long enough to propagate to the system.sessions collection. + * New in MongoDB 3.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/listSessions/} */ $listSessions: { @@ -4914,6 +5693,7 @@ export namespace Aggregation.Stage { export interface $lookup { /** * Performs a left outer join to another collection in the same database to filter in documents from the "joined" collection for processing. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/} */ $lookup: { @@ -4944,7 +5724,7 @@ export namespace Aggregation.Stage { * The pipeline cannot include the $out stage or the $merge stage. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. * The pipeline cannot directly access the joined document fields. Instead, define variables for the joined document fields using the let option and then reference the variables in the pipeline stages. */ - pipeline?: UntypedPipeline; + pipeline?: Pipeline; /** * Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the from collection. If the specified name already exists in the input document, the existing field is overwritten. @@ -4960,6 +5740,7 @@ export namespace Aggregation.Stage { export interface $match { /** * Filters the document stream to allow only matching documents to pass unmodified into the next pipeline stage. $match uses standard MongoDB queries. For each input document, outputs either one document (a match) or zero documents (no match). + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/} */ $match: Query; @@ -4984,7 +5765,7 @@ export namespace Aggregation.Stage { /** * Field or fields that act as a unique identifier for a document. The identifier determines if a results document matches an existing document in the output collection. */ - on?: string | string[]; + on?: string | unknown[]; /** * Specifies variables for use in the whenMatched pipeline. @@ -4994,7 +5775,7 @@ export namespace Aggregation.Stage { /** * The behavior of $merge if a result document and an existing document in the collection have the same value for the specified on field(s). */ - whenMatched?: WhenMatched | UntypedPipeline; + whenMatched?: WhenMatched | UpdatePipeline; /** * The behavior of $merge if a result document does not match an existing document in the out collection. @@ -5010,9 +5791,51 @@ export namespace Aggregation.Stage { export interface $out { /** * Writes the resulting documents of the aggregation pipeline to a collection. To use the $out stage, it must be the last stage in the pipeline. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/out/} */ - $out: string | OutCollection; + $out: { + /** + * The output collection name. + */ + coll: string; + + /** + * The output database name. If omitted, defaults to the current database. + */ + db?: string; + + /** + * Specifies the configuration to use when writing to a time series collection. + * The timeField is required. All other fields are optional. + */ + timeseries?: { + /** + * The name of the field which contains the date in each time series document. + */ + timeField: string; + + /** + * The name of the field which contains metadata in each time series document. + */ + metaField?: string; + + /** + * The granularity of time measurements. Value can be seconds, minutes, or hours. + */ + granularity?: TimeGranularity; + + /** + * The maximum time span between measurements in a bucket. + */ + bucketMaxSpanSeconds?: Int; + + /** + * The interval that determines the starting timestamp for a new bucket. + */ + bucketRoundingSeconds?: Int; + }; + }; } /** @@ -5022,6 +5845,7 @@ export namespace Aggregation.Stage { export interface $planCacheStats { /** * Returns plan cache information for a collection. + * New in MongoDB 4.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/planCacheStats/} */ $planCacheStats: Record; @@ -5034,10 +5858,47 @@ export namespace Aggregation.Stage { export interface $project { /** * Reshapes each document in the stream, such as by adding new fields or removing existing fields. For each input document, outputs one document. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/} */ - $project: {} & { - [specification: string]: Expression | ExpressionMap; + $project: {} & { [specification: string]: Expression }; + } + + /** + * A type describing the `$rankFusion` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/rankFusion/} + */ + export interface $rankFusion { + /** + * Combines multiple pipelines using rank-based fusion to create hybrid search results. + * New in MongoDB 8.1. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/rankFusion/} + */ + $rankFusion: { + /** + * An object that specifies the pipelines to combine with rank fusion. + */ + input: { + /** + * Map from name to ranked input pipeline. Each pipeline must operate on the same collection. + */ + pipelines: Pipeline; + }; + + /** + * An object that specifies how to combine the ranked results. + */ + combination?: { + /** + * Map from pipeline name to weight (non-negative number). If unspecified, default weight is 1 for each pipeline. + */ + weights?: Number; + }; + + /** + * Set to true to include detailed scoring information. + */ + scoreDetails?: boolean; }; } @@ -5048,6 +5909,7 @@ export namespace Aggregation.Stage { export interface $redact { /** * Reshapes each document in the stream by restricting the content for each document based on information stored in the documents themselves. Incorporates the functionality of $project and $match. Can be used to implement field level redaction. For each input document, outputs either one or zero documents. + * New in MongoDB 2.6. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/redact/} */ $redact: Expression; @@ -5060,6 +5922,7 @@ export namespace Aggregation.Stage { export interface $replaceRoot { /** * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceRoot/} */ $replaceRoot: { newRoot: ResolvesToObject }; @@ -5073,11 +5936,50 @@ export namespace Aggregation.Stage { /** * Replaces a document with the specified embedded document. The operation replaces all existing fields in the input document, including the _id field. Specify a document embedded in the input document to promote the embedded document to the top level. * Alias for $replaceRoot. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceWith/} */ $replaceWith: ResolvesToObject; } + /** + * A type describing the `$rerank` operator. + * @see {@link https://www.mongodb.com/docs/vector-search/query/aggregation-stages/rerank/} + */ + export interface $rerank { + /** + * Reranks documents using a Voyage AI reranking model to improve relevance scoring. + * New in MongoDB 8.3. + * @see {@link https://www.mongodb.com/docs/vector-search/query/aggregation-stages/rerank/} + */ + $rerank: { + /** + * Name of the Voyage AI reranking model to use (e.g. rerank-2.5, rerank-2.5-lite). + */ + model: string; + + /** + * Query object for reranking. + */ + query: { + /** + * Query text used to score document relevance. + */ + text: string; + }; + + /** + * Field path or array of field paths to use for reranking. + */ + path: string | unknown[]; + + /** + * Maximum number of documents to send to Voyage AI for reranking. Value must be between 1 and 1000. + */ + numDocsToRerank: Int; + }; + } + /** * A type describing the `$sample` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/} @@ -5085,6 +5987,7 @@ export namespace Aggregation.Stage { export interface $sample { /** * Randomly selects the specified number of documents from its input. + * New in MongoDB 3.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/} */ $sample: { @@ -5095,6 +5998,98 @@ export namespace Aggregation.Stage { }; } + /** + * A type describing the `$score` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/} + */ + export interface $score { + /** + * Computes and returns a new score as metadata. It also optionally normalizes the input + * scores, by default to a range between zero and one. + * New in MongoDB 8.2. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/} + */ + $score: { + /** + * Computes a new value from the input scores and stores the value in the $meta keyword + * score. Returns an error for non-numeric inputs. + */ + score: Expression; + + /** + * Normalizes the score to the range of 0 to 1. Value can be: + * - none: Doesn't normalize. If omitted, defaults to none. + * - sigmoid: Applies the sigmoid expression: 1 / (1 + e^-x). + * - minMaxScaler: Applies the $minMaxScaler window function. + */ + normalization?: ScoreNormalization; + + /** + * Number to multiply the score expression by after normalization. + */ + weight?: Expression; + + /** + * Specifies if $score computes and populates the $scoreDetails metadata field for each + * output document. + */ + scoreDetails?: boolean; + }; + } + + /** + * A type describing the `$scoreFusion` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/} + */ + export interface $scoreFusion { + /** + * Combines multiple pipelines using relative score fusion to create hybrid search results. + * New in MongoDB 8.0. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/} + */ + $scoreFusion: { + /** + * An object that specifies the pipelines to combine with score fusion. + */ + input: { + /** + * Map from name to input pipeline. Each pipeline must be operating on the same collection. + */ + pipelines: Pipeline; + + /** + * Normalizes the score to the range 0 to 1 before combining the results. Value can be none, sigmoid or minMaxScaler. + */ + normalization: string; + }; + + /** + * An object that specifies how to combine the scores. + */ + combination?: { + /** + * Map from pipeline name to weight (non-negative number). If unspecified, default weight is 1 for each pipeline. + */ + weights?: Number; + + /** + * Specifies method for combining scores. Value can be avg or expression. Default is avg. + */ + method?: string; + + /** + * Custom expression used when combination.method is set to expression. + */ + expression?: Expression; + }; + + /** + * Set to true to include detailed scoring information. + */ + scoreDetails?: boolean; + }; + } + /** * A type describing the `$search` operator. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/} @@ -5103,6 +6098,7 @@ export namespace Aggregation.Stage { /** * Performs a full-text search of the field or fields in an Atlas collection. * NOTE: $search is only available for MongoDB Atlas clusters, and is not available for self-managed deployments. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/search/} */ $search: SearchOperator & { @@ -5114,7 +6110,7 @@ export namespace Aggregation.Stage { /** * Specifies the highlighting options for displaying search terms in their original context. */ - highlight?: SearchHighlight; + highlight?: Record; /** * Parallelize search across segments on dedicated search nodes. @@ -5148,6 +6144,11 @@ export namespace Aggregation.Stage { */ sort?: Record; + /** + * Object that sets the context of the query to the specified embedded document field. You must also specify `returnStoredSource` and set it to `true`. + */ + returnScope?: Record; + /** * Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. */ @@ -5168,6 +6169,7 @@ export namespace Aggregation.Stage { /** * Returns different types of metadata result documents for the Atlas Search query against an Atlas collection. * NOTE: $searchMeta is only available for MongoDB Atlas clusters running MongoDB v4.4.9 or higher, and is not available for self-managed deployments. + * New in MongoDB 5.0. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/searchMeta/} */ $searchMeta: SearchOperator & { @@ -5180,6 +6182,16 @@ export namespace Aggregation.Stage { * Document that specifies the count options for retrieving a count of the results. */ count?: Record; + + /** + * Object that sets the context of the query to the specified embedded document field. You must also specify `returnStoredSource` and set it to `true` if your cluster MongoDB version is less than 8.2. + */ + returnScope?: Record; + + /** + * Flag that specifies whether to perform a full document lookup on the backend database or return only stored source fields directly from Atlas Search. + */ + returnStoredSource?: boolean; }; } @@ -5191,6 +6203,7 @@ export namespace Aggregation.Stage { /** * Adds new fields to documents. Outputs documents that contain all existing fields from the input documents and newly added fields. * Alias for $addFields. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/set/} */ $set: {} & { [field: string]: Expression }; @@ -5245,6 +6258,7 @@ export namespace Aggregation.Stage { export interface $skip { /** * Skips the first n documents where n is the specified skip number and passes the remaining documents unmodified to the pipeline. For each input document, outputs either zero documents (for the first n documents) or one document (if after the first n documents). + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/} */ $skip: Int; @@ -5257,6 +6271,7 @@ export namespace Aggregation.Stage { export interface $sort { /** * Reorders the document stream by a specified sort key. Only the order changes; the documents remain unmodified. For each input document, outputs one document. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort/} */ $sort: {} & { [sort: string]: Expression | SortSpec }; @@ -5269,6 +6284,7 @@ export namespace Aggregation.Stage { export interface $sortByCount { /** * Groups incoming documents based on the value of a specified expression, then computes the count of documents in each distinct group. + * New in MongoDB 3.4. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/} */ $sortByCount: Expression; @@ -5294,7 +6310,7 @@ export namespace Aggregation.Stage { * An aggregation pipeline to apply to the specified coll. * The pipeline cannot include the $out and $merge stages. Starting in v6.0, the pipeline can contain the Atlas Search $search stage as the first stage inside the pipeline. */ - pipeline?: UntypedPipeline; + pipeline?: Pipeline; }; } @@ -5306,6 +6322,7 @@ export namespace Aggregation.Stage { /** * Removes or excludes fields from documents. * Alias for $project stage that removes or excludes fields. + * New in MongoDB 4.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/unset/} */ $unset: [...UnprefixedFieldPath[]]; @@ -5318,6 +6335,7 @@ export namespace Aggregation.Stage { export interface $unwind { /** * Deconstructs an array field from the input documents to output a document for each element. Each output document replaces the array with an element value. For each input document, outputs n documents where n is the number of array elements and can be zero for an empty array. + * New in MongoDB 2.2. * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/unwind/} */ $unwind: { @@ -5347,6 +6365,7 @@ export namespace Aggregation.Stage { export interface $vectorSearch { /** * The $vectorSearch stage performs an ANN or ENN search on a vector in the specified field. + * New in MongoDB 6.0. * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/} */ $vectorSearch: { @@ -5366,9 +6385,10 @@ export namespace Aggregation.Stage { path: string; /** - * Array of numbers that represent the query vector. The number type must match the indexed field value type. + * Array of numbers or a BinData value that represent the query vector. The number type + * must match the indexed field value type. */ - queryVector: unknown[]; + queryVector: bson.Binary | unknown[]; /** * This is required if numCandidates is omitted. false to run ANN search. true to run ENN search. @@ -5376,7 +6396,7 @@ export namespace Aggregation.Stage { exact?: boolean; /** - * Any match query that compares an indexed field with a boolean, date, objectId, number (not decimals), string, or UUID to use as a pre-filter. + * Any match query that compares an indexed field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. */ filter?: Query; @@ -5385,15 +6405,230 @@ export namespace Aggregation.Stage { * Number of nearest neighbors to use during the search. Value must be less than or equal to (<=) 10000. You can't specify a number less than the number of documents to return (limit). */ numCandidates?: Int; + + /** + * If true, the search returns only the stored source fields configured on the index directly from the index and skips a full document lookup. If omitted, the default value is false. + */ + returnStoredSource?: boolean; + + /** + * Configure how MongoDB Vector Search scores documents that contain nested arrays. + */ + nestedOptions?: { + /** + * Specifies how to score documents that contain nested arrays. Value can be avg or max. + */ + scoreMode?: string; + }; + + /** + * Any match query that compares an indexed top-level field with a boolean, date, objectId, number, string, or UUID to use as a pre-filter. Only valid if `nestedRoot` is specified in the index definition. + */ + parentFilter?: Query; }; } } +export namespace Aggregation.Update { + /** + * A type describing the `$addToSet` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/} + */ + export interface $addToSet { + /** + * Adds a value to an array unless the value is already present. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/addToSet/} + */ + $addToSet: {} & { [field: string]: any }; + } -export type Int = number | bson.Int32; -export type Double = number | bson.Double; -export type Decimal = bson.Decimal128; -export type Regex = RegExp | bson.BSONRegExp; -export type Long = bigint | bson.Long; + /** + * A type describing the `$bit` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/bit/} + */ + export interface $bit { + /** + * Performs bitwise updates of integer values. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/bit/} + */ + $bit: { + /** + * Each field maps to an object containing exactly one bitwise operation: + * and, or, or xor. + */ + } & { [field: string]: BitwiseOperation }; + } + + /** + * A type describing the `$currentDate` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/currentDate/} + */ + export interface $currentDate { + /** + * Sets the value of a field to the current date as either a Date or Timestamp. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/currentDate/} + */ + $currentDate: { + /** + * The value for each field can be either: + * - true, to set the field to the current date. + * - a document with $type set to "date" or "timestamp". + */ + } & { [field: string]: boolean | Record }; + } + + /** + * A type describing the `$inc` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/inc/} + */ + export interface $inc { + /** + * Increments a field by the specified numeric amount. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/inc/} + */ + $inc: {} & { [field: string]: Number }; + } + + /** + * A type describing the `$max` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/max/} + */ + export interface $max { + /** + * Updates a field only if the specified value is greater than the current field value. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/max/} + */ + $max: {} & { [field: string]: any }; + } + + /** + * A type describing the `$min` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/min/} + */ + export interface $min { + /** + * Updates a field only if the specified value is less than the current field value. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/min/} + */ + $min: {} & { [field: string]: any }; + } + + /** + * A type describing the `$mul` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/mul/} + */ + export interface $mul { + /** + * Multiplies the value of a field by the specified number. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/mul/} + */ + $mul: {} & { [field: string]: Number }; + } + + /** + * A type describing the `$pop` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pop/} + */ + export interface $pop { + /** + * Removes the first or last element of an array. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pop/} + */ + $pop: {} & { [field: string]: Int }; + } + + /** + * A type describing the `$pull` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pull/} + */ + export interface $pull { + /** + * Removes all array elements that match a specified value or condition. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pull/} + */ + $pull: {} & { [field: string]: FieldQuery }; + } + + /** + * A type describing the `$pullAll` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pullAll/} + */ + export interface $pullAll { + /** + * Removes all matching values from an array. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/pullAll/} + */ + $pullAll: {} & { [field: string]: unknown[] }; + } + + /** + * A type describing the `$push` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/push/} + */ + export interface $push { + /** + * Appends a specified value to an array, with optional modifiers. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/push/} + */ + $push: {} & { [field: string]: any }; + } + + /** + * A type describing the `$rename` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/rename/} + */ + export interface $rename { + /** + * Renames a field. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/rename/} + */ + $rename: {} & { [field: string]: string }; + } + + /** + * A type describing the `$set` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/set/} + */ + export interface $set { + /** + * Sets the value of a field. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/set/} + */ + $set: {} & { [field: string]: any }; + } + + /** + * A type describing the `$setOnInsert` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/setOnInsert/} + */ + export interface $setOnInsert { + /** + * Sets the value of a field if an update with upsert creates a new document. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/setOnInsert/} + */ + $setOnInsert: {} & { [field: string]: any }; + } + + /** + * A type describing the `$unset` operator. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/unset/} + */ + export interface $unset { + /** + * Removes the specified field from a document. + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/update/unset/} + */ + $unset: {} & { [field: string]: any }; + } +} + +export type Int = number | bson.Int32 | { $numberInt: string }; +export type Double = number | bson.Double | { $numberDouble: string }; +export type Decimal = bson.Decimal128 | { $numberDecimal: string }; +export type Regex = + | RegExp + | bson.BSONRegExp + | { pattern: string; options?: string }; +export type Long = bigint | bson.Long | { $numberLong: string }; export type Javascript = bson.Code | Function | string; export type Geometry = | { type: 'Point'; coordinates: number[] } @@ -5423,8 +6658,14 @@ export type SearchPath = | UnprefixedFieldPath | UnprefixedFieldPath[] | { wildcard: string }; +export type BitwiseOperation = + | { and: Int | Long } + | { or: Int | Long } + | { xor: Int | Long }; export type SearchScore = unknown; export type Granularity = string; +export type TimeGranularity = 'seconds' | 'minutes' | 'hours'; +export type ScoreNormalization = 'none' | 'sigmoid' | 'minMaxScaler'; export type FullDocument = string; export type FullDocumentBeforeChange = string; export type AccumulatorPercentile = string; @@ -5459,36 +6700,27 @@ export type Stage = | Aggregation.Stage.$addFields | Aggregation.Stage.$bucket | Aggregation.Stage.$bucketAuto - | Aggregation.Stage.$changeStream - | Aggregation.Stage.$changeStreamSplitLargeEvent - | Aggregation.Stage.$collStats | Aggregation.Stage.$count - | Aggregation.Stage.$currentOp | Aggregation.Stage.$densify - | Aggregation.Stage.$documents | Aggregation.Stage.$facet | Aggregation.Stage.$fill - | Aggregation.Stage.$geoNear | Aggregation.Stage.$graphLookup | Aggregation.Stage.$group - | Aggregation.Stage.$indexStats | Aggregation.Stage.$limit - | Aggregation.Stage.$listLocalSessions | Aggregation.Stage.$listSampledQueries | Aggregation.Stage.$listSearchIndexes - | Aggregation.Stage.$listSessions | Aggregation.Stage.$lookup | Aggregation.Stage.$match - | Aggregation.Stage.$merge - | Aggregation.Stage.$out | Aggregation.Stage.$planCacheStats | Aggregation.Stage.$project + | Aggregation.Stage.$rankFusion | Aggregation.Stage.$redact | Aggregation.Stage.$replaceRoot | Aggregation.Stage.$replaceWith + | Aggregation.Stage.$rerank | Aggregation.Stage.$sample - | Aggregation.Stage.$search - | Aggregation.Stage.$searchMeta + | Aggregation.Stage.$score + | Aggregation.Stage.$scoreFusion | Aggregation.Stage.$set | Aggregation.Stage.$setWindowFields | Aggregation.Stage.$shardedDataDistribution @@ -5497,14 +6729,15 @@ export type Stage = | Aggregation.Stage.$sortByCount | Aggregation.Stage.$unionWith | Aggregation.Stage.$unset - | Aggregation.Stage.$unwind - | Aggregation.Stage.$vectorSearch; + | Aggregation.Stage.$unwind; export type Pipeline = Stage[]; +export type UpdatePipeline = UpdateStage[]; export type UntypedPipeline = Pipeline; export type Query = | QueryOperator | Partial<{ [k in keyof S]: Condition }> | Aggregation.Query.$and + | Aggregation.Query.$comment | Aggregation.Query.$expr | Aggregation.Query.$jsonSchema | Aggregation.Query.$nor @@ -5518,6 +6751,7 @@ export type Accumulator = | Aggregation.Accumulator.$avg | Aggregation.Accumulator.$bottom | Aggregation.Accumulator.$bottomN + | Aggregation.Accumulator.$concatArrays | Aggregation.Accumulator.$count | Aggregation.Accumulator.$first | Aggregation.Accumulator.$firstN @@ -5531,6 +6765,7 @@ export type Accumulator = | Aggregation.Accumulator.$minN | Aggregation.Accumulator.$percentile | Aggregation.Accumulator.$push + | Aggregation.Accumulator.$setUnion | Aggregation.Accumulator.$stdDevPop | Aggregation.Accumulator.$stdDevSamp | Aggregation.Accumulator.$sum @@ -5602,6 +6837,10 @@ export type ResolvesToDouble = | Aggregation.Expression.$radiansToDegrees | Aggregation.Expression.$rand | Aggregation.Expression.$round + | Aggregation.Expression.$sigmoid + | Aggregation.Expression.$similarityCosine + | Aggregation.Expression.$similarityDotProduct + | Aggregation.Expression.$similarityEuclidean | Aggregation.Expression.$sin | Aggregation.Expression.$sinh | Aggregation.Expression.$sqrt @@ -5618,6 +6857,7 @@ export type ResolvesToString = | string | Aggregation.Expression.$concat | Aggregation.Expression.$dateToString + | Aggregation.Expression.$hexHash | Aggregation.Expression.$ltrim | Aggregation.Expression.$replaceAll | Aggregation.Expression.$replaceOne @@ -5638,14 +6878,20 @@ export type ResolvesToObject = | Record | Aggregation.Expression.$arrayToObject | Aggregation.Expression.$dateToParts + | Aggregation.Expression.$deserializeEJSON | Aggregation.Expression.$mergeObjects | Aggregation.Expression.$regexFind + | Aggregation.Expression.$serializeEJSON | Aggregation.Expression.$setField + | Aggregation.Expression.$toObject | Aggregation.Expression.$unsetField; export type ResolvesToArray = | ResolvesToAny | ArrayFieldPath | unknown[] + | Aggregation.Accumulator.$concatArrays + | Aggregation.Accumulator.$setUnion + | Aggregation.Expression.$bottomN | Aggregation.Expression.$concatArrays | Aggregation.Expression.$filter | Aggregation.Expression.$firstN @@ -5664,15 +6910,19 @@ export type ResolvesToArray = | Aggregation.Expression.$slice | Aggregation.Expression.$sortArray | Aggregation.Expression.$split + | Aggregation.Expression.$toArray + | Aggregation.Expression.$topN | Aggregation.Expression.$zip; export type ResolvesToBinData = | ResolvesToAny | BinDataFieldPath - | bson.Binary; + | bson.Binary + | Aggregation.Expression.$hash; export type ResolvesToObjectId = | ResolvesToAny | ObjectIdFieldPath | bson.ObjectId + | Aggregation.Expression.$createObjectId | Aggregation.Expression.$toObjectId; export type ResolvesToBool = | ResolvesToAny @@ -5751,6 +7001,7 @@ export type ResolvesToInt = | Aggregation.Expression.$strLenCP | Aggregation.Expression.$strcasecmp | Aggregation.Expression.$subtract + | Aggregation.Expression.$subtype | Aggregation.Expression.$toInt | Aggregation.Expression.$week | Aggregation.Expression.$year; @@ -5804,6 +7055,7 @@ export type AccumulatorOperator = | Aggregation.Accumulator.$avg | Aggregation.Accumulator.$bottom | Aggregation.Accumulator.$bottomN + | Aggregation.Accumulator.$concatArrays | Aggregation.Accumulator.$count | Aggregation.Accumulator.$covariancePop | Aggregation.Accumulator.$covarianceSamp @@ -5823,10 +7075,12 @@ export type AccumulatorOperator = | Aggregation.Accumulator.$median | Aggregation.Accumulator.$mergeObjects | Aggregation.Accumulator.$min + | Aggregation.Accumulator.$minMaxScaler | Aggregation.Accumulator.$minN | Aggregation.Accumulator.$percentile | Aggregation.Accumulator.$push | Aggregation.Accumulator.$rank + | Aggregation.Accumulator.$setUnion | Aggregation.Accumulator.$shift | Aggregation.Accumulator.$stdDevPop | Aggregation.Accumulator.$stdDevSamp @@ -5838,6 +7092,7 @@ export type Window = | Aggregation.Accumulator.$avg | Aggregation.Accumulator.$bottom | Aggregation.Accumulator.$bottomN + | Aggregation.Accumulator.$concatArrays | Aggregation.Accumulator.$count | Aggregation.Accumulator.$covariancePop | Aggregation.Accumulator.$covarianceSamp @@ -5856,10 +7111,12 @@ export type Window = | Aggregation.Accumulator.$maxN | Aggregation.Accumulator.$median | Aggregation.Accumulator.$min + | Aggregation.Accumulator.$minMaxScaler | Aggregation.Accumulator.$minN | Aggregation.Accumulator.$percentile | Aggregation.Accumulator.$push | Aggregation.Accumulator.$rank + | Aggregation.Accumulator.$setUnion | Aggregation.Accumulator.$shift | Aggregation.Accumulator.$stdDevPop | Aggregation.Accumulator.$stdDevSamp @@ -5885,6 +7142,8 @@ export type ExpressionOperator = | Aggregation.Expression.$bitNot | Aggregation.Expression.$bitOr | Aggregation.Expression.$bitXor + | Aggregation.Expression.$bottom + | Aggregation.Expression.$bottomN | Aggregation.Expression.$bsonSize | Aggregation.Expression.$case | Aggregation.Expression.$ceil @@ -5895,6 +7154,7 @@ export type ExpressionOperator = | Aggregation.Expression.$convert | Aggregation.Expression.$cos | Aggregation.Expression.$cosh + | Aggregation.Expression.$createObjectId | Aggregation.Expression.$dateAdd | Aggregation.Expression.$dateDiff | Aggregation.Expression.$dateFromParts @@ -5907,6 +7167,7 @@ export type ExpressionOperator = | Aggregation.Expression.$dayOfWeek | Aggregation.Expression.$dayOfYear | Aggregation.Expression.$degreesToRadians + | Aggregation.Expression.$deserializeEJSON | Aggregation.Expression.$divide | Aggregation.Expression.$eq | Aggregation.Expression.$exp @@ -5918,6 +7179,8 @@ export type ExpressionOperator = | Aggregation.Expression.$getField | Aggregation.Expression.$gt | Aggregation.Expression.$gte + | Aggregation.Expression.$hash + | Aggregation.Expression.$hexHash | Aggregation.Expression.$hour | Aggregation.Expression.$ifNull | Aggregation.Expression.$in @@ -5971,12 +7234,17 @@ export type ExpressionOperator = | Aggregation.Expression.$round | Aggregation.Expression.$rtrim | Aggregation.Expression.$second + | Aggregation.Expression.$serializeEJSON | Aggregation.Expression.$setDifference | Aggregation.Expression.$setEquals | Aggregation.Expression.$setField | Aggregation.Expression.$setIntersection | Aggregation.Expression.$setIsSubset | Aggregation.Expression.$setUnion + | Aggregation.Expression.$sigmoid + | Aggregation.Expression.$similarityCosine + | Aggregation.Expression.$similarityDotProduct + | Aggregation.Expression.$similarityEuclidean | Aggregation.Expression.$sin | Aggregation.Expression.$sinh | Aggregation.Expression.$size @@ -5993,10 +7261,12 @@ export type ExpressionOperator = | Aggregation.Expression.$substrBytes | Aggregation.Expression.$substrCP | Aggregation.Expression.$subtract + | Aggregation.Expression.$subtype | Aggregation.Expression.$sum | Aggregation.Expression.$switch | Aggregation.Expression.$tan | Aggregation.Expression.$tanh + | Aggregation.Expression.$toArray | Aggregation.Expression.$toBool | Aggregation.Expression.$toDate | Aggregation.Expression.$toDecimal @@ -6005,9 +7275,12 @@ export type ExpressionOperator = | Aggregation.Expression.$toInt | Aggregation.Expression.$toLong | Aggregation.Expression.$toLower + | Aggregation.Expression.$toObject | Aggregation.Expression.$toObjectId | Aggregation.Expression.$toString | Aggregation.Expression.$toUpper + | Aggregation.Expression.$top + | Aggregation.Expression.$topN | Aggregation.Expression.$trim | Aggregation.Expression.$trunc | Aggregation.Expression.$tsIncrement @@ -6019,6 +7292,7 @@ export type ExpressionOperator = | Aggregation.Expression.$zip; export type ResolvesToAny = | Aggregation.Expression.$arrayElemAt + | Aggregation.Expression.$bottom | Aggregation.Expression.$cond | Aggregation.Expression.$convert | Aggregation.Expression.$first @@ -6032,7 +7306,8 @@ export type ResolvesToAny = | Aggregation.Expression.$meta | Aggregation.Expression.$min | Aggregation.Expression.$reduce - | Aggregation.Expression.$switch; + | Aggregation.Expression.$switch + | Aggregation.Expression.$top; export type SwitchBranch = Aggregation.Expression.$case; export type FieldQuery = | Aggregation.Query.$all @@ -6071,6 +7346,7 @@ export type QueryOperator = | Aggregation.Query.$box | Aggregation.Query.$center | Aggregation.Query.$centerSphere + | Aggregation.Query.$comment | Aggregation.Query.$elemMatch | Aggregation.Query.$eq | Aggregation.Query.$exists @@ -6111,6 +7387,8 @@ export type SearchOperator = | Aggregation.Search.Facet | Aggregation.Search.GeoShape | Aggregation.Search.GeoWithin + | Aggregation.Search.HasAncestor + | Aggregation.Search.HasRoot | Aggregation.Search.In | Aggregation.Search.MoreLikeThis | Aggregation.Search.Near @@ -6119,7 +7397,15 @@ export type SearchOperator = | Aggregation.Search.Range | Aggregation.Search.Regex | Aggregation.Search.Text + | Aggregation.Search.VectorSearch | Aggregation.Search.Wildcard; +export type UpdateStage = + | Aggregation.Stage.$addFields + | Aggregation.Stage.$project + | Aggregation.Stage.$replaceRoot + | Aggregation.Stage.$replaceWith + | Aggregation.Stage.$set + | Aggregation.Stage.$unset; export type StageOperator = | Aggregation.Stage.$addFields | Aggregation.Stage.$bucket @@ -6148,10 +7434,14 @@ export type StageOperator = | Aggregation.Stage.$out | Aggregation.Stage.$planCacheStats | Aggregation.Stage.$project + | Aggregation.Stage.$rankFusion | Aggregation.Stage.$redact | Aggregation.Stage.$replaceRoot | Aggregation.Stage.$replaceWith + | Aggregation.Stage.$rerank | Aggregation.Stage.$sample + | Aggregation.Stage.$score + | Aggregation.Stage.$scoreFusion | Aggregation.Stage.$search | Aggregation.Stage.$searchMeta | Aggregation.Stage.$set @@ -6164,3 +7454,51 @@ export type StageOperator = | Aggregation.Stage.$unset | Aggregation.Stage.$unwind | Aggregation.Stage.$vectorSearch; +export type InputStage = + | Aggregation.Stage.$changeStream + | Aggregation.Stage.$collStats + | Aggregation.Stage.$currentOp + | Aggregation.Stage.$documents + | Aggregation.Stage.$geoNear + | Aggregation.Stage.$indexStats + | Aggregation.Stage.$listLocalSessions + | Aggregation.Stage.$listSessions + | Aggregation.Stage.$search + | Aggregation.Stage.$searchMeta + | Aggregation.Stage.$vectorSearch; +export type OutputStage = + | Aggregation.Stage.$changeStreamSplitLargeEvent + | Aggregation.Stage.$merge + | Aggregation.Stage.$out; +export type Update = + | Aggregation.Update.$addToSet + | Aggregation.Update.$bit + | Aggregation.Update.$currentDate + | Aggregation.Update.$inc + | Aggregation.Update.$max + | Aggregation.Update.$min + | Aggregation.Update.$mul + | Aggregation.Update.$pop + | Aggregation.Update.$pull + | Aggregation.Update.$pullAll + | Aggregation.Update.$push + | Aggregation.Update.$rename + | Aggregation.Update.$set + | Aggregation.Update.$setOnInsert + | Aggregation.Update.$unset; +export type UpdateOperator = + | Aggregation.Update.$addToSet + | Aggregation.Update.$bit + | Aggregation.Update.$currentDate + | Aggregation.Update.$inc + | Aggregation.Update.$max + | Aggregation.Update.$min + | Aggregation.Update.$mul + | Aggregation.Update.$pop + | Aggregation.Update.$pull + | Aggregation.Update.$pullAll + | Aggregation.Update.$push + | Aggregation.Update.$rename + | Aggregation.Update.$set + | Aggregation.Update.$setOnInsert + | Aggregation.Update.$unset; diff --git a/packages/mql-typescript/package.json b/packages/mql-typescript/package.json index d47a14bc..986421f6 100644 --- a/packages/mql-typescript/package.json +++ b/packages/mql-typescript/package.json @@ -57,7 +57,7 @@ "check-ci": "npm run check", "test": "tsc --noEmit tests/**/*.ts", "reformat": "npm run prettier -- --write .", - "extract-metaschema": "json-refs resolve mongo-php-library/generator/config/schema.json | json-schema-to-zod -n Operator -o src/metaschema.ts && npm run prettier -- --write src/metaschema.ts", + "extract-metaschema": "ts-node src/build-metaschema.ts && npm run prettier -- --write src/metaschema.ts", "pregenerate-schema": "npm run extract-metaschema", "generate-schema": "ts-node src/cli.ts schema", "postgenerate-schema": "npm run prettier -- --write out/*", @@ -66,7 +66,7 @@ "postgenerate-tests": "npm run prettier -- --write tests/**/*.ts", "pregenerate-driver-schema": "npm run extract-metaschema", "generate-driver-schema": "ts-node src/cli.ts driver-schema", - "postgenerate-driver-schema": "yamlfix -c mongo-php-library/generator/config/.yamlfix.toml mongo-php-library/generator/config", + "postgenerate-driver-schema": "yamlfix -c mql-specifications/.yamlfix.toml mql-specifications/definitions", "format-generated-files": "npm run postgenerate-schema && npm run postgenerate-tests && npm run postgenerate-driver-schema" }, "devDependencies": { @@ -83,7 +83,6 @@ "gen-esm-wrapper": "^1.1.3", "js-yaml": "^4.1.1", "jsdom": "^24.1.3", - "json-refs": "^3.0.15", "json-schema-to-zod": "^2.6.0", "prettier": "^3.8.1", "ts-node": "^10.9.2", diff --git a/packages/mql-typescript/src/build-metaschema.ts b/packages/mql-typescript/src/build-metaschema.ts new file mode 100644 index 00000000..0d74a2ee --- /dev/null +++ b/packages/mql-typescript/src/build-metaschema.ts @@ -0,0 +1,77 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { jsonSchemaToZod } from 'json-schema-to-zod'; + +/** + * Generates `src/metaschema.ts` (the zod schema used to parse the operator + * definitions) directly from the JSON metaschema shipped in the + * `mql-specifications` submodule, so the zod definitions don't have to be + * maintained by hand. + * + * `json-schema-to-zod` expects a fully dereferenced schema and emits `z.any()` + * for any `$ref` it doesn't understand, while `json-refs` cannot inline the + * recursive `Argument.arguments` reference. We therefore dereference the + * `#/definitions/*` references ourselves, breaking reference cycles by + * replacing the recursive reference with an empty schema (which becomes + * `z.any()`). + */ + +type JsonSchema = Record; + +const schemaFile = path.resolve( + __dirname, + '..', + 'mql-specifications', + 'schemas', + 'operator.json', +); +const outputFile = path.resolve(__dirname, 'metaschema.ts'); + +const root = JSON.parse(fs.readFileSync(schemaFile, 'utf8')) as { + definitions: Record; +}; +const definitions = root.definitions; + +function dereference(node: unknown, stack: readonly string[]): unknown { + if (Array.isArray(node)) { + return node.map((item) => dereference(item, stack)); + } + + if (node && typeof node === 'object') { + const ref = (node as JsonSchema).$ref; + if (typeof ref === 'string') { + const match = /^#\/definitions\/(.+)$/.exec(ref); + if (!match) { + throw new Error(`Unsupported $ref: ${ref}`); + } + const name = match[1]; + if (stack.includes(name)) { + // Break the reference cycle. An empty schema is converted to + // `z.any()`, which accepts the recursive structure at runtime. + return {}; + } + if (!definitions[name]) { + throw new Error(`Unknown definition: ${name}`); + } + return dereference(definitions[name], [...stack, name]); + } + + return Object.fromEntries( + Object.entries(node).map(([key, value]) => [ + key, + dereference(value, stack), + ]), + ); + } + + return node; +} + +const operatorSchema = dereference(definitions.Operator, ['Operator']); + +const code = jsonSchemaToZod(operatorSchema as JsonSchema, { + name: 'Operator', + module: 'esm', +}); + +fs.writeFileSync(outputFile, code, 'utf8'); diff --git a/packages/mql-typescript/src/cli.ts b/packages/mql-typescript/src/cli.ts index c09366c6..f409fc17 100644 --- a/packages/mql-typescript/src/cli.ts +++ b/packages/mql-typescript/src/cli.ts @@ -6,28 +6,31 @@ import { DriverSchemaGenerator } from './driverSchema/driver-schema-generator'; import type { GeneratorBase } from './generator'; async function main() { + const filterOptions = { + category: { + type: 'string', + choices: ['accumulator', 'expression', 'query', 'search', 'stage'], + description: + 'The category of the operator to generate. If not provided, all categories will be used.', + }, + operator: { + type: 'string', + description: + 'The operator to generate. If not provided, all operators will be used.', + }, + } as const; + const argv = await yargs(hideBin(process.argv)) .command('schema', 'Generates schema from the php driver definitions') .command( 'tests', 'Generates tests from the php driver definitions and the docs examples', + filterOptions, ) .command( 'driver-schema', 'Updates the php driver definitions with the schema for the tests', - { - category: { - type: 'string', - choices: ['accumulator', 'expression', 'query', 'search', 'stage'], - description: - 'The category of the operator to update. If not provided, all categories will be updated.', - }, - operator: { - type: 'string', - description: - 'The operator to update the schema for. If not provided, all operators will be updated.', - }, - }, + filterOptions, ) .demandCommand(1, 'A command must be provided') .help().argv; diff --git a/packages/mql-typescript/src/driverSchema/driver-schema-generator.ts b/packages/mql-typescript/src/driverSchema/driver-schema-generator.ts index fb2a753e..13df396d 100644 --- a/packages/mql-typescript/src/driverSchema/driver-schema-generator.ts +++ b/packages/mql-typescript/src/driverSchema/driver-schema-generator.ts @@ -11,11 +11,13 @@ type TestType = NonNullable[number]; export class DriverSchemaGenerator extends GeneratorBase { private async getSchemaFromDocs(test: TestType): Promise { if (!test.link) { - console.error(`No docs reference found for ${test.name}`); + console.error(`No docs reference found for ${String(test.name)}`); return '// TODO: No docs reference found'; } - if (!test.pipeline) { - console.error(`No pipeline found for ${test.name} at ${test.link}`); + if (!('pipeline' in test) || !test.pipeline) { + console.error( + `No pipeline found for ${String(test.name)} at ${test.link}`, + ); return '// TODO: No pipeline found'; } @@ -24,7 +26,7 @@ export class DriverSchemaGenerator extends GeneratorBase { if (!schema) { console.error( - `Could not extract schema for ${test.name} at ${test.link}`, + `Could not extract schema for ${String(test.name)} at ${test.link}`, ); return '// TODO: No schema found in docs'; } @@ -45,8 +47,13 @@ export class DriverSchemaGenerator extends GeneratorBase { test: TestType; rawYaml: { tests: { name: string; schema: object | string }[] }; }): Promise { + if (test.name === undefined) { + return; + } + + const testName = test.name; const yamlTest = rawYaml.tests.find( - (t: { name: string }) => t.name === test.name, + (t: { name: string }) => t.name === testName, ); if (!yamlTest) { @@ -57,7 +64,7 @@ export class DriverSchemaGenerator extends GeneratorBase { } yamlTest.schema = - getStaticSchema({ category, operator, test: test.name }) ?? + getStaticSchema({ category, operator, test: testName }) ?? (await this.getSchemaFromDocs(test)); } @@ -86,7 +93,7 @@ export class DriverSchemaGenerator extends GeneratorBase { lineWidth: -1, }); - updatedYaml = `# $schema: ../schema.json\n${updatedYaml}`; + updatedYaml = `# $schema: ../../schemas/operator.json\n${updatedYaml}`; await fs.writeFile(operator.path, updatedYaml, 'utf8'); } diff --git a/packages/mql-typescript/src/driverSchema/static-schemas.ts b/packages/mql-typescript/src/driverSchema/static-schemas.ts index e2a26163..9452aeed 100644 --- a/packages/mql-typescript/src/driverSchema/static-schemas.ts +++ b/packages/mql-typescript/src/driverSchema/static-schemas.ts @@ -92,6 +92,35 @@ const inventorySchema: SchemaInfo = { }, }; +// The docs examples for these operators live on pages with several sibling +// examples, so the crawler cannot reliably infer their collection schema. +const zipCodeSchema: SchemaInfo = { + collectionName: 'addressBook', + schema: { + _id: { types: [{ bsonType: 'Int32' }] }, + address: { types: [{ bsonType: 'String' }] }, + zipCode: { + types: [ + { bsonType: 'String' }, + { bsonType: 'Int32' }, + { bsonType: 'Double' }, + { bsonType: 'Array', types: [{ bsonType: 'String' }] }, + ], + }, + }, +}; + +const salesByDateSchema: SchemaInfo = { + collectionName: 'sales', + schema: { + _id: { types: [{ bsonType: 'Int32' }] }, + item: { types: [{ bsonType: 'String' }] }, + price: { types: [{ bsonType: 'Decimal128' }] }, + quantity: { types: [{ bsonType: 'Int32' }] }, + date: { types: [{ bsonType: 'Date' }] }, + }, +}; + const mflixMoviesSchema: SchemaInfo = { collectionName: 'movies', schema: { @@ -1415,7 +1444,62 @@ type SchemaMap = { }; const staticSchemas: SchemaMap = { + accumulator: { + concatArrays: { + ['Warehouse collection']: { + collectionName: 'warehouses', + schema: { + instock: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + ordered: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + }, + }, + }, + setUnion: { + ['Flowers collection']: { + collectionName: 'flowers', + schema: { + flowerFieldA: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + flowerFieldB: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + }, + }, + }, + }, expression: { + concatArrays: { + Example: { + collectionName: 'warehouses', + schema: { + instock: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + ordered: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + }, + }, + }, + setUnion: { + Example: { + collectionName: 'flowers', + schema: { + flowerFieldA: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + flowerFieldB: { + types: [{ bsonType: 'Array', types: [{ bsonType: 'String' }] }], + }, + }, + }, + }, + serializeEJSON: mflixMoviesSchema, dateFromParts: { Example: { collectionName: 'sales', @@ -1496,6 +1580,15 @@ const staticSchemas: SchemaMap = { }, }, exists: inventorySchema, + gt: inventorySchema, + gte: inventorySchema, + lt: inventorySchema, + lte: inventorySchema, + nin: inventorySchema, + type: { + ['Querying by Data Type']: zipCodeSchema, + ['Querying by Array Type']: zipCodeSchema, + }, geoIntersects: geoPolygonSchema, geoWithin: geoPolygonSchema, jsonSchema: { @@ -1563,6 +1656,22 @@ const staticSchemas: SchemaMap = { wildcard: mflixMoviesSchema, }, stage: { + project: { + // The docs page for this example shares its insertion code with sibling + // examples, so the crawler cannot reliably infer the {x, y} collection. + 'Project New Array Fields': { + collectionName: 'TestCollection', + schema: { + _id: { types: [{ bsonType: 'ObjectId' }] }, + x: { types: [{ bsonType: 'Int32' }] }, + y: { types: [{ bsonType: 'Int32' }] }, + }, + }, + }, + group: { + ['Calculate Count Sum and Average']: salesByDateSchema, + ['Group by null']: salesByDateSchema, + }, sort: { collectionName: 'users', schema: { diff --git a/packages/mql-typescript/src/generator.ts b/packages/mql-typescript/src/generator.ts index a8591d3e..2e8a38d1 100644 --- a/packages/mql-typescript/src/generator.ts +++ b/packages/mql-typescript/src/generator.ts @@ -196,11 +196,16 @@ export abstract class GeneratorBase { protected configDir = path.join( __dirname, '..', - 'mongo-php-library', - 'generator', - 'config', + 'mql-specifications', + 'definitions', ); + // The `types` category describes closed-set types using a different schema + // (schemas/type.json); those types are modeled directly in the generator's + // type mappings. The `pipeline` category describes the top-level pipeline + // containers, which are also modeled directly as type mappings. + private static readonly ignoredCategories = new Set(['types', 'pipeline']); + private async *listCategories( filterRegex: RegExp | undefined, ): AsyncIterable<{ @@ -210,6 +215,9 @@ export abstract class GeneratorBase { for await (const folder of await fs.readdir(this.configDir, { withFileTypes: true, })) { + if (GeneratorBase.ignoredCategories.has(folder.name)) { + continue; + } if (folder.isDirectory() && filterRegex?.test(folder.name) !== false) { yield { category: folder.name, diff --git a/packages/mql-typescript/src/metaschema.ts b/packages/mql-typescript/src/metaschema.ts index d8b44d46..d4d1feeb 100644 --- a/packages/mql-typescript/src/metaschema.ts +++ b/packages/mql-typescript/src/metaschema.ts @@ -3,35 +3,82 @@ import { z } from 'zod'; export const Operator = z .object({ name: z.string().regex(new RegExp('^\\$?[a-z][a-zA-Z0-9]*$')), + minVersion: z + .string() + .regex(new RegExp('^[0-9]+\\.[0-9]+(\\.[1-9][0-9]*)?$')), link: z.string().url().regex(new RegExp('^https://')), + generic: z.array(z.string()).optional(), type: z.array( - z.enum([ - 'accumulator', - 'stage', - 'query', - 'fieldQuery', - 'filter', - 'window', - 'geometry', - 'switchBranch', - 'resolvesToAny', - 'resolvesToNumber', - 'resolvesToDouble', - 'resolvesToString', - 'resolvesToObject', - 'resolvesToArray', - 'resolvesToBinData', - 'resolvesToObjectId', - 'resolvesToBool', - 'resolvesToDate', - 'resolvesToNull', - 'resolvesToRegex', - 'resolvesToJavascript', - 'resolvesToInt', - 'resolvesToTimestamp', - 'resolvesToLong', - 'resolvesToDecimal', - 'searchOperator', + z.union([ + z.enum([ + 'pipeline', + 'accumulator', + 'stage', + 'updateStage', + 'inputStage', + 'outputStage', + 'query', + 'update', + 'fieldQuery', + 'filter', + 'window', + 'geometry', + 'switchBranch', + 'resolvesToAny', + 'resolvesToNumber', + 'resolvesToDouble', + 'resolvesToString', + 'resolvesToObject', + 'resolvesToArray', + 'resolvesToBinData', + 'resolvesToObjectId', + 'resolvesToBool', + 'resolvesToDate', + 'resolvesToNull', + 'resolvesToRegex', + 'resolvesToJavascript', + 'resolvesToInt', + 'resolvesToTimestamp', + 'resolvesToLong', + 'resolvesToDecimal', + 'searchOperator', + ]), + z.object({ + name: z.enum([ + 'pipeline', + 'accumulator', + 'stage', + 'updateStage', + 'inputStage', + 'outputStage', + 'query', + 'update', + 'fieldQuery', + 'filter', + 'window', + 'geometry', + 'switchBranch', + 'resolvesToAny', + 'resolvesToNumber', + 'resolvesToDouble', + 'resolvesToString', + 'resolvesToObject', + 'resolvesToArray', + 'resolvesToBinData', + 'resolvesToObjectId', + 'resolvesToBool', + 'resolvesToDate', + 'resolvesToNull', + 'resolvesToRegex', + 'resolvesToJavascript', + 'resolvesToInt', + 'resolvesToTimestamp', + 'resolvesToLong', + 'resolvesToDecimal', + 'searchOperator', + ]), + generic: z.string().optional(), + }), ]), ), encode: z.enum(['array', 'object', 'single']), @@ -42,90 +89,195 @@ export const Operator = z z .object({ name: z.string().regex(new RegExp('^([_$]?[a-z][a-zA-Z0-9]*|N)$')), + minVersion: z + .string() + .regex(new RegExp('^[0-9]+\\.[0-9]+(\\.[1-9][0-9]*)?$')) + .optional(), type: z.array( - z.enum([ - 'accumulator', - 'query', - 'fieldQuery', - 'pipeline', - 'untypedPipeline', - 'window', - 'expression', - 'expressionMap', - 'geometry', - 'fieldPath', - 'unprefixedFieldPath', - 'timeUnit', - 'sortSpec', - 'any', - 'granularity', - 'fullDocument', - 'fullDocumentBeforeChange', - 'accumulatorPercentile', - 'whenMatched', - 'whenNotMatched', - 'outCollection', - 'range', - 'sortBy', - 'geoPoint', - 'resolvesToNumber', - 'numberFieldPath', - 'number', - 'resolvesToDouble', - 'doubleFieldPath', - 'double', - 'resolvesToString', - 'stringFieldPath', - 'string', - 'resolvesToObject', - 'objectFieldPath', - 'object', - 'resolvesToArray', - 'arrayFieldPath', - 'array', - 'resolvesToBinData', - 'binDataFieldPath', - 'binData', - 'resolvesToObjectId', - 'objectIdFieldPath', - 'objectId', - 'resolvesToBool', - 'boolFieldPath', - 'bool', - 'resolvesToDate', - 'dateFieldPath', - 'date', - 'resolvesToNull', - 'nullFieldPath', - 'null', - 'resolvesToRegex', - 'regexFieldPath', - 'regex', - 'resolvesToJavascript', - 'javascriptFieldPath', - 'javascript', - 'resolvesToInt', - 'intFieldPath', - 'int', - 'resolvesToTimestamp', - 'timestampFieldPath', - 'timestamp', - 'resolvesToLong', - 'longFieldPath', - 'long', - 'resolvesToDecimal', - 'decimalFieldPath', - 'decimal', - 'searchPath', - 'searchScore', - 'searchOperator', - 'searchHighlight', + z.union([ + z.enum([ + 'stage', + 'updateStage', + 'inputStage', + 'outputStage', + 'accumulator', + 'query', + 'fieldQuery', + 'pipeline', + 'updatePipeline', + 'untypedPipeline', + 'window', + 'expression', + 'expressionMap', + 'geometry', + 'unprefixedFieldPath', + 'timeUnit', + 'sortSpec', + 'granularity', + 'timeGranularity', + 'fullDocument', + 'fullDocumentBeforeChange', + 'accumulatorPercentile', + 'whenMatched', + 'whenNotMatched', + 'scoreNormalization', + 'outCollection', + 'range', + 'sortBy', + 'geoPoint', + 'resolvesToAny', + 'fieldPath', + 'any', + 'resolvesToNumber', + 'numberFieldPath', + 'number', + 'resolvesToDouble', + 'doubleFieldPath', + 'double', + 'resolvesToString', + 'stringFieldPath', + 'string', + 'resolvesToObject', + 'objectFieldPath', + 'object', + 'resolvesToArray', + 'arrayFieldPath', + 'array', + 'resolvesToBinData', + 'binDataFieldPath', + 'binData', + 'resolvesToObjectId', + 'objectIdFieldPath', + 'objectId', + 'resolvesToBool', + 'boolFieldPath', + 'bool', + 'resolvesToDate', + 'dateFieldPath', + 'date', + 'resolvesToNull', + 'nullFieldPath', + 'null', + 'resolvesToRegex', + 'regexFieldPath', + 'regex', + 'resolvesToJavascript', + 'javascriptFieldPath', + 'javascript', + 'resolvesToInt', + 'intFieldPath', + 'int', + 'resolvesToTimestamp', + 'timestampFieldPath', + 'timestamp', + 'resolvesToLong', + 'longFieldPath', + 'long', + 'resolvesToDecimal', + 'decimalFieldPath', + 'decimal', + 'searchPath', + 'searchScore', + 'bitwiseOperation', + 'searchOperator', + ]), + z.object({ + name: z.enum([ + 'stage', + 'updateStage', + 'inputStage', + 'outputStage', + 'accumulator', + 'query', + 'fieldQuery', + 'pipeline', + 'updatePipeline', + 'untypedPipeline', + 'window', + 'expression', + 'expressionMap', + 'geometry', + 'unprefixedFieldPath', + 'timeUnit', + 'sortSpec', + 'granularity', + 'timeGranularity', + 'fullDocument', + 'fullDocumentBeforeChange', + 'accumulatorPercentile', + 'whenMatched', + 'whenNotMatched', + 'scoreNormalization', + 'outCollection', + 'range', + 'sortBy', + 'geoPoint', + 'resolvesToAny', + 'fieldPath', + 'any', + 'resolvesToNumber', + 'numberFieldPath', + 'number', + 'resolvesToDouble', + 'doubleFieldPath', + 'double', + 'resolvesToString', + 'stringFieldPath', + 'string', + 'resolvesToObject', + 'objectFieldPath', + 'object', + 'resolvesToArray', + 'arrayFieldPath', + 'array', + 'resolvesToBinData', + 'binDataFieldPath', + 'binData', + 'resolvesToObjectId', + 'objectIdFieldPath', + 'objectId', + 'resolvesToBool', + 'boolFieldPath', + 'bool', + 'resolvesToDate', + 'dateFieldPath', + 'date', + 'resolvesToNull', + 'nullFieldPath', + 'null', + 'resolvesToRegex', + 'regexFieldPath', + 'regex', + 'resolvesToJavascript', + 'javascriptFieldPath', + 'javascript', + 'resolvesToInt', + 'intFieldPath', + 'int', + 'resolvesToTimestamp', + 'timestampFieldPath', + 'timestamp', + 'resolvesToLong', + 'longFieldPath', + 'long', + 'resolvesToDecimal', + 'decimalFieldPath', + 'decimal', + 'searchPath', + 'searchScore', + 'bitwiseOperation', + 'searchOperator', + ]), + generic: z.string().optional(), + }), ]), ), description: z.string().optional(), optional: z.boolean().optional(), valueMin: z.number().optional(), valueMax: z.number().optional(), + minItems: z.number().int().gte(0).optional(), + maxItems: z.number().int().gte(0).optional(), variadic: z.enum(['array', 'object']).optional(), variadicMin: z.number().int().gte(0).optional(), default: z @@ -135,81 +287,149 @@ export const Operator = z syntheticVariables: z .array( z.object({ - name: z.string().regex(new RegExp('^[$]?[a-zA-Z0-9]*$')), + name: z.string().regex(new RegExp('^[$]?[a-zA-Z0-9]+$')), description: z.string().optional(), }), ) .optional(), + arguments: z.array(z.any()).optional(), }) .strict(), ) .optional(), tests: z .array( - z - .object({ - name: z.string(), - link: z.string().url().regex(new RegExp('^https://')).optional(), - pipeline: z.array(z.record(z.any())), - schema: z - .union([ - z.string(), - z.record( + z.union([ + z + .object({ + name: z.string(), + link: z.string().url().regex(new RegExp('^https://')).optional(), + pipeline: z.array(z.record(z.any())), + schema: z + .union([ z.record( - z - .object({ - types: z.array( - z.union([ - z - .object({ - bsonType: z.enum([ - 'Array', - 'Binary', - 'Boolean', - 'Code', - 'CodeWScope', - 'Date', - 'Decimal128', - 'Double', - 'Int32', - 'Int64', - 'Long', - 'MaxKey', - 'MinKey', - 'Null', - 'ObjectId', - 'BSONRegExp', - 'String', - 'BSONSymbol', - 'Timestamp', - 'Undefined', - 'Document', - 'Number', - ]), - }) - .strict(), - z - .object({ - bsonType: z.literal('Array'), - types: z.array(z.record(z.any())), - }) - .strict(), - z - .object({ - bsonType: z.literal('Document'), - fields: z.record(z.record(z.any())), - }) - .strict(), - ]), - ), - }) - .strict(), + z.record( + z + .object({ + types: z.array( + z.union([ + z + .object({ + bsonType: z.enum([ + 'Array', + 'Binary', + 'Boolean', + 'Code', + 'CodeWScope', + 'Date', + 'Decimal128', + 'Double', + 'Int32', + 'Int64', + 'Long', + 'MaxKey', + 'MinKey', + 'Null', + 'ObjectId', + 'BSONRegExp', + 'String', + 'BSONSymbol', + 'Timestamp', + 'Undefined', + 'Document', + 'Number', + ]), + }) + .strict(), + z + .object({ + bsonType: z.literal('Array'), + types: z.array(z.record(z.any())), + }) + .strict(), + z + .object({ + bsonType: z.literal('Document'), + fields: z.record(z.record(z.any())), + }) + .strict(), + ]), + ), + }) + .strict(), + ), ), - ), - ]) - .optional(), - }) - .strict(), + z.string(), + ]) + .optional(), + }) + .strict(), + z + .object({ + name: z.string(), + link: z.string().url().regex(new RegExp('^https://')).optional(), + filter: z.record(z.any()), + update: z.record(z.any()), + schema: z + .union([ + z.record( + z.record( + z + .object({ + types: z.array( + z.union([ + z + .object({ + bsonType: z.enum([ + 'Array', + 'Binary', + 'Boolean', + 'Code', + 'CodeWScope', + 'Date', + 'Decimal128', + 'Double', + 'Int32', + 'Int64', + 'Long', + 'MaxKey', + 'MinKey', + 'Null', + 'ObjectId', + 'BSONRegExp', + 'String', + 'BSONSymbol', + 'Timestamp', + 'Undefined', + 'Document', + 'Number', + ]), + }) + .strict(), + z + .object({ + bsonType: z.literal('Array'), + types: z.array(z.record(z.any())), + }) + .strict(), + z + .object({ + bsonType: z.literal('Document'), + fields: z.record(z.record(z.any())), + }) + .strict(), + ]), + ), + }) + .strict(), + ), + ), + z.string(), + ]) + .optional(), + }) + .strict(), + ]), ) .optional(), }) diff --git a/packages/mql-typescript/src/schema-generator.ts b/packages/mql-typescript/src/schema-generator.ts index aa7d129a..7de97838 100644 --- a/packages/mql-typescript/src/schema-generator.ts +++ b/packages/mql-typescript/src/schema-generator.ts @@ -4,13 +4,24 @@ import { GeneratorBase } from './generator'; import { Operator } from './metaschema'; import { capitalize } from './utils'; -type ArgType = NonNullable< - typeof Operator._type.arguments ->[number]['type'][number]; +type ArgumentT = NonNullable[number]; -type SyntheticVariables = NonNullable< - typeof Operator._type.arguments ->[number]['syntheticVariables']; +type TypeRef = ArgumentT['type'][number]; + +// The plain (string) form of a type reference. Type references may also be +// objects carrying a `generic` type parameter, which the generator ignores. +type ArgType = Extract; + +type SyntheticVariables = ArgumentT['syntheticVariables']; + +/** + * Normalizes a type reference (which may be a plain name or an object carrying + * a generic type parameter) to its plain name. Generics are not reflected in + * the generated TypeScript definitions. + */ +function typeRefName(type: T | { name: T }): T { + return typeof type === 'string' ? type : type.name; +} export class SchemaGenerator extends GeneratorBase { private schemaOutputFile = path.resolve( @@ -86,8 +97,13 @@ export class SchemaGenerator extends GeneratorBase { 'UnprefixedFieldPath[]', '{ wildcard: string }', ], + bitwiseOperation: [ + '({ and: Int | Long } | { or: Int | Long } | { xor: Int | Long })', + ], searchScore: ['unknown'], granularity: ['string'], + timeGranularity: ['"seconds"', '"minutes"', '"hours"'], + scoreNormalization: ['"none"', '"sigmoid"', '"minMaxScaler"'], fullDocument: ['string'], fullDocumentBeforeChange: ['string'], accumulatorPercentile: ['string'], @@ -122,6 +138,7 @@ export class SchemaGenerator extends GeneratorBase { ], stage_S: [this.toTypeName('StageOperator')], pipeline_S: [this.toTypeName('stage[]')], + updatePipeline_S: [this.toTypeName('updateStage[]')], untypedPipeline: [this.toTypeName('Pipeline')], query_S: [ this.toTypeName('QueryOperator'), @@ -275,7 +292,7 @@ export class SchemaGenerator extends GeneratorBase { // TBD: Nested fields type AFieldPath = KeysOfAType & string; - type FieldExpression = { [k: string]: FieldPath }; + type FieldExpression = { [k: string]: Expression }; type MultiAnalyzerSpec = { value: KeysOfAType; @@ -313,17 +330,25 @@ export class SchemaGenerator extends GeneratorBase { return undefined; } - private emitArg( - arg: NonNullable[number], - named: boolean, - ): void { + private emitArg(arg: ArgumentT, named: boolean): void { if (named) { this.emit(`${arg.name}${arg.optional ? '?' : ''}: `); } - const allowsArrays = arg.type.includes('array'); - const argTypes = arg.type - .filter((t) => t !== 'array') + // Object-typed arguments may carry their own nested `arguments`, which + // describe a typed object structure rather than a free-form record. The + // recursive `arguments` reference is typed as `any` in the generated + // metaschema (the reference cycle is broken during extraction), so we + // restore the element type here. + if (arg.arguments) { + this.emitObjectFromArgs(arg.arguments as ArgumentT[]); + return; + } + + const types = arg.type.map(typeRefName); + const allowsArrays = types.includes('array'); + const nonArrayTypes = types.filter((t) => t !== 'array'); + const argTypes = nonArrayTypes .map((type) => { const name = this.getArgumentTypeName(type, arg.syntheticVariables); if (!name) { @@ -334,8 +359,10 @@ export class SchemaGenerator extends GeneratorBase { .join(' | '); if (allowsArrays) { - if (arg.type.length > 1) { - this.emit(`(${argTypes}) | (${argTypes})[]`); + // `array` is a top-level alternative: the argument may be a plain + // (untyped) array in addition to any of the other listed types. + if (nonArrayTypes.length > 0) { + this.emit(`(${argTypes}) | unknown[]`); } else { this.emit('unknown[]'); } @@ -344,6 +371,22 @@ export class SchemaGenerator extends GeneratorBase { } } + /** + * Emits a typed object literal from a list of (sub-)arguments. Used for + * object-typed arguments that describe a nested, typed structure. + */ + private emitObjectFromArgs(args: ArgumentT[]): void { + this.emit('{'); + for (const arg of args) { + if (arg.description) { + this.emitComment(arg.description); + } + this.emitArg(arg, true); + this.emit(';'); + } + this.emit('}'); + } + /** * This is explicitly handling the case of $slice where an argument in the middle of the array is optional. * This is not allowed by typescript, so we need to convert the array into a union of tuples. @@ -432,11 +475,19 @@ export class SchemaGenerator extends GeneratorBase { ); this.emit(`export interface ${ifaceName} {`); if (parsed.description) { - this.emitComment(parsed.description, parsed.link); + // Append a "New in MongoDB" note derived from the operator's + // `minVersion`, matching how the documentation annotates operators. + // `1.0` denotes the initial release (i.e. the operator has always + // existed), so we omit the note in that case. + const versionNote = + parsed.minVersion === '1.0' + ? '' + : `\nNew in MongoDB ${parsed.minVersion}.`; + this.emitComment(`${parsed.description}${versionNote}`, parsed.link); } this.emit(`${parsed.name}:`); for (const type of parsed.type) { - (this.typeMappings[`${type}_S`] ??= []).push( + (this.typeMappings[`${typeRefName(type)}_S`] ??= []).push( `${namespace}.${ifaceName}`, ); } @@ -521,7 +572,9 @@ export class SchemaGenerator extends GeneratorBase { `RecordWithStaticFields<${objectType}, ${this.toComment( arg.description, )} ${arg.type - .map((t) => this.getArgumentTypeName(t)) + .map((t) => + this.getArgumentTypeName(typeRefName(t)), + ) .join(' | ')}>`, ); } diff --git a/packages/mql-typescript/src/testGenerator/test-generator.ts b/packages/mql-typescript/src/testGenerator/test-generator.ts index 8d9ca707..96db46d5 100644 --- a/packages/mql-typescript/src/testGenerator/test-generator.ts +++ b/packages/mql-typescript/src/testGenerator/test-generator.ts @@ -58,8 +58,12 @@ export class TestGenerator extends GeneratorBase { return `undefined`; case 'Number': return 'number'; + case 'Array': + return 'unknown[]'; + case 'Document': + return 'Record'; default: - throw new Error(`Unknown BSON type: ${type}`); + throw new Error(`Unknown BSON type: ${String(type)}`); } } @@ -115,7 +119,9 @@ export class TestGenerator extends GeneratorBase { } if (stage instanceof bson.BSONRegExp) { - return `new bson.BSONRegExp('${stage.pattern}', '${stage.options}')`; + return `new bson.BSONRegExp(${JSON.stringify( + stage.pattern, + )}, ${JSON.stringify(stage.options)})`; } if ('$code' in stage && typeof stage.$code === 'string') { @@ -141,14 +147,16 @@ export class TestGenerator extends GeneratorBase { operator: string, test: TestType, ): void { - if (!test.pipeline) { - this.emit(`// TODO: No pipeline found for ${operator}.${test.name}\n`); + if (!('pipeline' in test) || !test.pipeline) { + this.emit( + `// TODO: No pipeline found for ${operator}.${String(test.name)}\n`, + ); return; } if (!test.schema || typeof test.schema === 'string') { this.emit( - `// TODO: no schema found for ${operator}.${test.name}${test.schema ? `: ${test.schema}` : ''}\n`, + `// TODO: no schema found for ${operator}.${String(test.name)}${test.schema ? `: ${test.schema}` : ''}\n`, ); return; } @@ -168,7 +176,9 @@ export class TestGenerator extends GeneratorBase { // Some pipelines project to new types, which is not supported by the static type system. // In this case, we typecast to any to suppress the type error. const unsupportedStage = - unsupportedAggregations[category]?.[operator]?.[test.name]; + test.name === undefined + ? undefined + : unsupportedAggregations[category]?.[operator]?.[test.name]; const isUnsupportedStage = unsupportedStage && i >= unsupportedStage.stage; @@ -191,6 +201,14 @@ export class TestGenerator extends GeneratorBase { protected override async generateImpl(yamlFiles: YamlFiles): Promise { for await (const file of yamlFiles) { + // Update operators describe `filter`/`update` examples rather than + // aggregation pipelines, which the test harness cannot currently render + // (there is no associated collection schema to type them against), so we + // skip generating spec files for them. + if (file.category === 'update') { + continue; + } + const namespace = `${capitalize(file.category)}Operators`; const basePath = path.resolve( diff --git a/packages/mql-typescript/src/testGenerator/unsupported-aggregations.ts b/packages/mql-typescript/src/testGenerator/unsupported-aggregations.ts index c89f0378..1def97bd 100644 --- a/packages/mql-typescript/src/testGenerator/unsupported-aggregations.ts +++ b/packages/mql-typescript/src/testGenerator/unsupported-aggregations.ts @@ -14,6 +14,18 @@ export const unsupportedAggregations: { }, }, expression: { + top: { + Example: { stage: 0, comment: nestedFieldsExplanation }, + }, + topN: { + Example: { stage: 0, comment: nestedFieldsExplanation }, + }, + bottom: { + Example: { stage: 0, comment: nestedFieldsExplanation }, + }, + bottomN: { + Example: { stage: 0, comment: nestedFieldsExplanation }, + }, arrayToObject: { ['$objectToArray and $arrayToObject Example']: { stage: 1 }, }, @@ -49,6 +61,11 @@ export const unsupportedAggregations: { comment: '$map references the variable names defined in the `as` field, which is not available statically', }, + 'Use Array Index': { + stage: 0, + comment: + '$map references the variable names defined in the `as` and `arrayIndexAs` fields, which is not available statically', + }, }, objectToArray: { '$objectToArray to Sum Nested Fields': { stage: 1 }, @@ -109,6 +126,26 @@ export const unsupportedAggregations: { }, }, search: { + hasRoot: { + 'Simple Query': { + stage: 0, + comment: nestedFieldsExplanation, + }, + 'Multi-Level Query': { + stage: 0, + comment: nestedFieldsExplanation, + }, + 'Compound Query': { + stage: 0, + comment: nestedFieldsExplanation, + }, + }, + hasAncestor: { + Example: { + stage: 0, + comment: nestedFieldsExplanation, + }, + }, embeddedDocument: { 'Query for Matching Embedded Documents Only': { stage: 2, @@ -192,6 +229,18 @@ export const unsupportedAggregations: { 'the output field of the $bucket stage generates new fields that are not available statically', }, }, + lookup: { + 'Perform an Uncorrelated Subquery with $lookup': { + stage: 0, + comment: + 'the lookup sub-pipeline references fields from the joined collection that are not available statically', + }, + 'Perform a Concise Correlated Subquery with $lookup': { + stage: 0, + comment: + 'the lookup sub-pipeline references the variables defined in the `let` field, which are not available statically', + }, + }, currentOp: { 'Inactive Sessions': { stage: 1, diff --git a/packages/mql-typescript/tests/accumulator/concatArrays.spec.ts b/packages/mql-typescript/tests/accumulator/concatArrays.spec.ts new file mode 100644 index 00000000..09836d33 --- /dev/null +++ b/packages/mql-typescript/tests/accumulator/concatArrays.spec.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Warehouse collection + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatArrays/#example} + */ +function test0() { + type warehouses = { + instock: Array; + ordered: Array; + }; + + const aggregation: schema.Pipeline = [ + { $project: { items: { $concatArrays: ['$instock', '$ordered'] } } }, + ]; +} diff --git a/packages/mql-typescript/tests/accumulator/minMaxScaler.spec.ts b/packages/mql-typescript/tests/accumulator/minMaxScaler.spec.ts new file mode 100644 index 00000000..07e7db73 --- /dev/null +++ b/packages/mql-typescript/tests/accumulator/minMaxScaler.spec.ts @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Normalize values with custom range + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/minMaxScaler/#examples} + */ +function test0() { + type example = { + a: number; + }; + + const aggregation: schema.Pipeline = [ + { + $setWindowFields: { + sortBy: { a: 1 }, + output: { + scaled: { $minMaxScaler: { input: '$a' } }, + scaledTo100: { $minMaxScaler: { input: '$a', min: 0, max: 100 } }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/accumulator/setUnion.spec.ts b/packages/mql-typescript/tests/accumulator/setUnion.spec.ts new file mode 100644 index 00000000..e1025460 --- /dev/null +++ b/packages/mql-typescript/tests/accumulator/setUnion.spec.ts @@ -0,0 +1,27 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Flowers collection + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/setUnion/#example} + */ +function test0() { + type flowers = { + flowerFieldA: Array; + flowerFieldB: Array; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + flowerFieldA: 1, + flowerFieldB: 1, + allValues: { $setUnion: ['$flowerFieldA', '$flowerFieldB'] }, + _id: 0, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/avg.spec.ts b/packages/mql-typescript/tests/expression/avg.spec.ts index 60f4acd0..585cc536 100644 --- a/packages/mql-typescript/tests/expression/avg.spec.ts +++ b/packages/mql-typescript/tests/expression/avg.spec.ts @@ -20,8 +20,8 @@ function test0() { const aggregation: schema.Pipeline = [ { $project: { - quizAvg: { $avg: '$quizzes' }, - labAvg: { $avg: '$labs' }, + quizAvg: { $avg: ['$quizzes'] }, + labAvg: { $avg: ['$labs'] }, examAvg: { $avg: ['$final', '$midterm'] }, }, }, diff --git a/packages/mql-typescript/tests/expression/bottom.spec.ts b/packages/mql-typescript/tests/expression/bottom.spec.ts new file mode 100644 index 00000000..c0e26dab --- /dev/null +++ b/packages/mql-typescript/tests/expression/bottom.spec.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom-array-operator/#example} + */ +function test0() { + type games = { + results: Array<{ + playerId: string; + score: number; + }>; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $project: { + bottomScore: { + $bottom: { + sortBy: { score: -1 }, + output: ['$playerId', '$score'], + input: '$results', + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/expression/bottomN.spec.ts b/packages/mql-typescript/tests/expression/bottomN.spec.ts new file mode 100644 index 00000000..dee7411c --- /dev/null +++ b/packages/mql-typescript/tests/expression/bottomN.spec.ts @@ -0,0 +1,36 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomN-array-operator/#example} + */ +function test0() { + type games = { + results: Array<{ + playerId: string; + score: number; + }>; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $project: { + bottomScores: { + $bottomN: { + n: 3, + sortBy: { score: -1 }, + output: ['$playerId', '$score'], + input: '$results', + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/expression/convert.spec.ts b/packages/mql-typescript/tests/expression/convert.spec.ts index 0e111048..5f34eb13 100644 --- a/packages/mql-typescript/tests/expression/convert.spec.ts +++ b/packages/mql-typescript/tests/expression/convert.spec.ts @@ -87,3 +87,43 @@ function test0() { } as any, ]; } + +/** + * Convert Hexadecimal String to Integer + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/convert/#base-conversion} + */ +function test1() { + type data = { + _id: number; + hexString: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + decimalValue: { + $convert: { input: '$hexString', to: 'int', base: 16 }, + }, + }, + }, + ]; +} + +/** + * Convert Integer to Binary String + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/convert/#base-conversion} + */ +function test2() { + type data = { + _id: number; + value: bson.Int32 | number; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + binaryString: { $convert: { input: '$value', to: 'string', base: 2 } }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/createObjectId.spec.ts b/packages/mql-typescript/tests/expression/createObjectId.spec.ts new file mode 100644 index 00000000..c347bd80 --- /dev/null +++ b/packages/mql-typescript/tests/expression/createObjectId.spec.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/createObjectId/#example} + */ +function test0() { + // TODO: no schema found for createObjectId.Example +} diff --git a/packages/mql-typescript/tests/expression/deserializeEJSON.spec.ts b/packages/mql-typescript/tests/expression/deserializeEJSON.spec.ts new file mode 100644 index 00000000..9d37118e --- /dev/null +++ b/packages/mql-typescript/tests/expression/deserializeEJSON.spec.ts @@ -0,0 +1,127 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Deserialize Extended JSON Document + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/#deserialize-extended-json-document} + */ +function test0() { + type movies = { + _id: bson.ObjectId; + title: string; + year: bson.Int32 | number; + runtime: bson.Int32 | number; + released: Date; + cast: unknown[]; + genres: unknown[]; + directors: unknown[]; + }; + + const aggregation: schema.Pipeline = [ + { $match: { title: 'Inception' } }, + { + $project: { + original: '$$ROOT', + serialized: { $serializeEJSON: { input: '$$ROOT' } }, + }, + }, + { + $project: { + title: '$original.title', + deserialized: { $deserializeEJSON: { input: '$serialized' } }, + }, + }, + ]; +} + +/** + * Parse JSON String and Deserialize + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/#parse-json-string-and-deserialize} + */ +function test1() { + type TestCollection = { + jsonData: string; + }; + + const aggregation: schema.Pipeline = [ + { + $documents: [ + { + jsonData: + '{"_id":{"$oid":"507f1f77bcf86cd799439011"},"title":"The Matrix","year":{"$numberInt":"1999"},"rating":{"$numberDouble":"8.7"}}', + }, + ], + }, + { + $project: { parsed: { $convert: { input: '$jsonData', to: 'object' } } }, + }, + { $project: { movie: { $deserializeEJSON: { input: '$parsed' } } } }, + ]; +} + +/** + * Deserialize Specific Fields + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/#deserialize-specific-fields} + */ +function test2() { + type movies = { + _id: bson.ObjectId; + title: string; + released: Date; + runtime: bson.Int32 | number; + imdb: { + rating: bson.Double | number; + }; + }; + + const aggregation: schema.Pipeline = [ + { $match: { title: 'Inception' } }, + { + $project: { + title: 1, + serializedMetadata: { + $serializeEJSON: { + input: { + releaseDate: '$released', + runtime: '$runtime', + rating: '$imdb.rating', + }, + }, + }, + }, + }, + { + $project: { + title: 1, + metadata: { $deserializeEJSON: { input: '$serializedMetadata' } }, + }, + }, + ]; +} + +/** + * Use onError for Error Handling + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/deserializeEJSON/#use-onerror-for-error-handling} + */ +function test3() { + type data = { + _id: bson.ObjectId; + ejsonField: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + result: { + $deserializeEJSON: { + input: '$ejsonField', + onError: { error: 'Invalid EJSON format' }, + }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/hash.spec.ts b/packages/mql-typescript/tests/expression/hash.spec.ts new file mode 100644 index 00000000..ca4dd21f --- /dev/null +++ b/packages/mql-typescript/tests/expression/hash.spec.ts @@ -0,0 +1,76 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Hash a Field Value + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/#hash-a-field-value} + */ +function test0() { + type files = { + _id: number; + filename: string; + hash: bson.Binary; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + filename: 1, + hash: { $hash: { input: '$filename', algorithm: 'sha256' } }, + }, + }, + ]; +} + +/** + * Hash a Literal String + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/#hash-a-literal-string} + */ +function test1() { + type TestCollection = { + val: string; + }; + + const aggregation: schema.Pipeline = [ + { $documents: [{ val: 'hello' }] }, + { + $project: { + _id: 0, + hash: { $hash: { input: '$val', algorithm: 'xxh64' } }, + }, + }, + ]; +} + +/** + * Hash BinData + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/#hash-bindata} + */ +function test2() { + type binaries = { + _id: number; + data: bson.Binary; + }; + + const aggregation: schema.Pipeline = [ + { $project: { hash: { $hash: { input: '$data', algorithm: 'sha256' } } } }, + ]; +} + +/** + * Null or Missing Input + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hash/#null-or-missing-input} + */ +function test3() { + type TestCollection = { + val: null; + }; + + const aggregation: schema.Pipeline = [ + { $documents: [{ val: null }, {}] }, + { $project: { hash: { $hash: { input: '$val', algorithm: 'sha256' } } } }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/hexHash.spec.ts b/packages/mql-typescript/tests/expression/hexHash.spec.ts new file mode 100644 index 00000000..cc9c5477 --- /dev/null +++ b/packages/mql-typescript/tests/expression/hexHash.spec.ts @@ -0,0 +1,45 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Hash a Field Value + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hexHash/#hash-a-field-value} + */ +function test0() { + type files = { + _id: number; + filename: string; + hexHash: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + filename: 1, + hexHash: { $hexHash: { input: '$filename', algorithm: 'sha256' } }, + }, + }, + ]; +} + +/** + * Null or Missing Input + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/hexHash/#null-or-missing-input} + */ +function test1() { + type TestCollection = { + val: null; + }; + + const aggregation: schema.Pipeline = [ + { $documents: [{ val: null }, {}] }, + { + $project: { + hexHash: { $hexHash: { input: '$val', algorithm: 'sha256' } }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/map.spec.ts b/packages/mql-typescript/tests/expression/map.spec.ts index ffae3cd2..ac9b3f56 100644 --- a/packages/mql-typescript/tests/expression/map.spec.ts +++ b/packages/mql-typescript/tests/expression/map.spec.ts @@ -87,3 +87,31 @@ function test2() { } as any, ]; } + +/** + * Use Array Index + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/map/} + */ +function test3() { + type data = { + scores: Array; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' ($map references the variable names defined in the `as` and `arrayIndexAs` fields, which is not available statically). + */ + { + $project: { + result: { + $map: { + input: '$scores', + as: 'score', + arrayIndexAs: 'idx', + in: { $add: ['$$score', '$$idx'] }, + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/expression/replaceAll.spec.ts b/packages/mql-typescript/tests/expression/replaceAll.spec.ts index e1bc4153..c8b7ff3c 100644 --- a/packages/mql-typescript/tests/expression/replaceAll.spec.ts +++ b/packages/mql-typescript/tests/expression/replaceAll.spec.ts @@ -5,8 +5,8 @@ import type * as schema from '../../out/schema'; import * as bson from 'bson'; /** - * Example - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceAll/#example} + * Replace Using a String + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceAll/#replace-using-a-string} */ function test0() { type inventory = { @@ -28,3 +28,28 @@ function test0() { }, ]; } + +/** + * Replace Using Regex + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceAll/#replace-using-regex} + */ +function test1() { + type inventory = { + _id: number; + item: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + item: { + $replaceAll: { + input: '$item', + find: new bson.BSONRegExp('\\bblue paint\\b', ''), + replacement: 'red paint', + }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/replaceOne.spec.ts b/packages/mql-typescript/tests/expression/replaceOne.spec.ts index 99b1cbbe..09c91e1f 100644 --- a/packages/mql-typescript/tests/expression/replaceOne.spec.ts +++ b/packages/mql-typescript/tests/expression/replaceOne.spec.ts @@ -28,3 +28,28 @@ function test0() { }, ]; } + +/** + * Replace Using Regex + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/replaceOne/#replace-using-regex} + */ +function test1() { + type inventory = { + _id: number; + item: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + item: { + $replaceOne: { + input: '$item', + find: new bson.BSONRegExp('\\bblue paint\\b', ''), + replacement: 'red paint', + }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/serializeEJSON.spec.ts b/packages/mql-typescript/tests/expression/serializeEJSON.spec.ts new file mode 100644 index 00000000..af60c119 --- /dev/null +++ b/packages/mql-typescript/tests/expression/serializeEJSON.spec.ts @@ -0,0 +1,137 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Canonical Extended JSON Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/#canonical-extended-json-example} + */ +function test0() { + type movies = { + _id: bson.ObjectId; + title: string; + year: bson.Int32 | number; + runtime: bson.Int32 | number; + released: Date; + cast: unknown[]; + genres: unknown[]; + directors: unknown[]; + }; + + const aggregation: schema.Pipeline = [ + { $match: { title: 'Inception' } }, + { $project: { ejson: { $serializeEJSON: { input: '$$ROOT' } } } }, + ]; +} + +/** + * Relaxed Extended JSON Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/#relaxed-extended-json-example} + */ +function test1() { + type movies = { + _id: bson.ObjectId; + title: string; + year: bson.Int32 | number; + runtime: bson.Int32 | number; + released: Date; + cast: unknown[]; + genres: unknown[]; + directors: unknown[]; + }; + + const aggregation: schema.Pipeline = [ + { $match: { title: 'Inception' } }, + { + $project: { + ejson: { $serializeEJSON: { input: '$$ROOT', relaxed: true } }, + }, + }, + ]; +} + +/** + * Convert to JSON String + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/#convert-to-json-string} + */ +function test2() { + type movies = { + _id: bson.ObjectId; + title: string; + year: bson.Int32 | number; + released: Date; + }; + + const aggregation: schema.Pipeline = [ + { $match: { title: 'The Godfather' } }, + { + $project: { + title: 1, + jsonString: { $toString: { $serializeEJSON: { input: '$$ROOT' } } }, + }, + }, + ]; +} + +/** + * Serialize Specific Fields + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/#serialize-specific-fields} + */ +function test3() { + type movies = { + _id: bson.ObjectId; + title: string; + year: bson.Int32 | number; + released: Date; + runtime: bson.Int32 | number; + imdb: { + rating: bson.Double | number; + }; + }; + + const aggregation: schema.Pipeline = [ + { $match: { year: { $gte: 2010 } } }, + { + $project: { + title: 1, + metadataEJSON: { + $serializeEJSON: { + input: { + releaseDate: '$released', + runtime: '$runtime', + imdbRating: '$imdb.rating', + }, + }, + }, + }, + }, + ]; +} + +/** + * Use onError for Error Handling + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/serializeEJSON/#use-onerror-for-error-handling} + */ +function test4() { + type movies = { + _id: bson.ObjectId; + title: string; + customField: string; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + title: 1, + ejson: { + $serializeEJSON: { + input: '$customField', + onError: { error: 'Serialization failed' }, + }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/sigmoid.spec.ts b/packages/mql-typescript/tests/expression/sigmoid.spec.ts new file mode 100644 index 00000000..91dab8cf --- /dev/null +++ b/packages/mql-typescript/tests/expression/sigmoid.spec.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sigmoid/#examples} + */ +function test0() { + type scores = { + _id: bson.ObjectId; + score: bson.Double | number; + }; + + const aggregation: schema.Pipeline = [ + { $set: { scaled: { $sigmoid: '$score' } } }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/similarityCosine.spec.ts b/packages/mql-typescript/tests/expression/similarityCosine.spec.ts new file mode 100644 index 00000000..6214a409 --- /dev/null +++ b/packages/mql-typescript/tests/expression/similarityCosine.spec.ts @@ -0,0 +1,28 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityCosine/#example} + */ +function test0() { + type vectors = { + _id: number; + a: Array; + b: Array; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + raw: { $similarityCosine: { vectors: ['$a', '$b'] } }, + normalized: { + $similarityCosine: { vectors: ['$a', '$b'], score: true }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/similarityDotProduct.spec.ts b/packages/mql-typescript/tests/expression/similarityDotProduct.spec.ts new file mode 100644 index 00000000..a6f26032 --- /dev/null +++ b/packages/mql-typescript/tests/expression/similarityDotProduct.spec.ts @@ -0,0 +1,28 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityDotProduct/#example} + */ +function test0() { + type vectors = { + _id: number; + a: Array; + b: Array; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + raw: { $similarityDotProduct: { vectors: ['$a', '$b'] } }, + normalized: { + $similarityDotProduct: { vectors: ['$a', '$b'], score: true }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/similarityEuclidean.spec.ts b/packages/mql-typescript/tests/expression/similarityEuclidean.spec.ts new file mode 100644 index 00000000..8ec54850 --- /dev/null +++ b/packages/mql-typescript/tests/expression/similarityEuclidean.spec.ts @@ -0,0 +1,28 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/similarityEuclidean/#example} + */ +function test0() { + type vectors = { + _id: number; + a: Array; + b: Array; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + raw: { $similarityEuclidean: { vectors: ['$a', '$b'] } }, + normalized: { + $similarityEuclidean: { vectors: ['$a', '$b'], score: true }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/subtype.spec.ts b/packages/mql-typescript/tests/expression/subtype.spec.ts new file mode 100644 index 00000000..7b69cbe0 --- /dev/null +++ b/packages/mql-typescript/tests/expression/subtype.spec.ts @@ -0,0 +1,19 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/subtype/} + */ +function test0() { + type data = { + myBinDataField: bson.Binary; + }; + + const aggregation: schema.Pipeline = [ + { $project: { result: { $subtype: '$myBinDataField' } } }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/toArray.spec.ts b/packages/mql-typescript/tests/expression/toArray.spec.ts new file mode 100644 index 00000000..23927237 --- /dev/null +++ b/packages/mql-typescript/tests/expression/toArray.spec.ts @@ -0,0 +1,40 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Convert String to Array + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toArray/#convert-string-to-array} + */ +function test0() { + type jsonStrings = { + _id: number; + }; + + const aggregation: schema.Pipeline = [ + { + $project: { + _id: 0, + numbers: { $toArray: '[1, 2, 3]' }, + documents: { $toArray: '[{"a": 1}, {"b": 2}]' }, + }, + }, + ]; +} + +/** + * Convert binData to Array + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toArray/#convert-bindata-to-array} + */ +function test1() { + type t = { + _id: number; + v: bson.Binary; + }; + + const aggregation: schema.Pipeline = [ + { $project: { _id: 0, original: '$v', asArray: { $toArray: '$v' } } }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/toObject.spec.ts b/packages/mql-typescript/tests/expression/toObject.spec.ts new file mode 100644 index 00000000..1cc320f8 --- /dev/null +++ b/packages/mql-typescript/tests/expression/toObject.spec.ts @@ -0,0 +1,20 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Convert String to Object + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/toObject/#convert-string-to-object} + */ +function test0() { + type jsonStrings = { + _id: number; + config: string; + }; + + const aggregation: schema.Pipeline = [ + { $project: { _id: 0, parsedConfig: { $toObject: '$config' } } }, + ]; +} diff --git a/packages/mql-typescript/tests/expression/top.spec.ts b/packages/mql-typescript/tests/expression/top.spec.ts new file mode 100644 index 00000000..1d160192 --- /dev/null +++ b/packages/mql-typescript/tests/expression/top.spec.ts @@ -0,0 +1,35 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/top-array-operator/#example} + */ +function test0() { + type games = { + results: Array<{ + playerId: string; + score: number; + }>; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $project: { + topScore: { + $top: { + sortBy: { score: -1 }, + output: ['$playerId', '$score'], + input: '$results', + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/expression/topN.spec.ts b/packages/mql-typescript/tests/expression/topN.spec.ts new file mode 100644 index 00000000..3aa12423 --- /dev/null +++ b/packages/mql-typescript/tests/expression/topN.spec.ts @@ -0,0 +1,36 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/topN-array-operator/#example} + */ +function test0() { + type games = { + results: Array<{ + playerId: string; + score: number; + }>; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $project: { + topScores: { + $topN: { + n: 3, + sortBy: { score: -1 }, + output: ['$playerId', '$score'], + input: '$results', + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/query/comment.spec.ts b/packages/mql-typescript/tests/query/comment.spec.ts new file mode 100644 index 00000000..0f34750b --- /dev/null +++ b/packages/mql-typescript/tests/query/comment.spec.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Attach a Comment to an Aggregation Expression + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/comment/#attach-a-comment-to-an-aggregation-expression} + */ +function test0() { + // TODO: no schema found for comment.Attach a Comment to an Aggregation Expression +} diff --git a/packages/mql-typescript/tests/query/elemMatch.spec.ts b/packages/mql-typescript/tests/query/elemMatch.spec.ts index 4bd3ff84..4bb8a098 100644 --- a/packages/mql-typescript/tests/query/elemMatch.spec.ts +++ b/packages/mql-typescript/tests/query/elemMatch.spec.ts @@ -60,3 +60,17 @@ function test2() { { $match: { results: { $elemMatch: { product: { $ne: 'xyz' } } } } }, ]; } + +/** + * Using $or with $elemMatch + */ +function test3() { + // TODO: no schema found for elemMatch.Using $or with $elemMatch: // TODO: No docs reference found +} + +/** + * Single field operator + */ +function test4() { + // TODO: no schema found for elemMatch.Single field operator: // TODO: No docs reference found +} diff --git a/packages/mql-typescript/tests/query/exists.spec.ts b/packages/mql-typescript/tests/query/exists.spec.ts index 8a2eeb0f..b8afd20c 100644 --- a/packages/mql-typescript/tests/query/exists.spec.ts +++ b/packages/mql-typescript/tests/query/exists.spec.ts @@ -39,3 +39,20 @@ function test1() { { $match: { qty: { $exists: true } } }, ]; } + +/** + * Missing Field + */ +function test2() { + type inventory = { + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; + tags: Array; + }; + + const aggregation: schema.Pipeline = [ + { $match: { qty: { $exists: false } } }, + ]; +} diff --git a/packages/mql-typescript/tests/query/expr.spec.ts b/packages/mql-typescript/tests/query/expr.spec.ts index da3c9a40..9097767e 100644 --- a/packages/mql-typescript/tests/query/expr.spec.ts +++ b/packages/mql-typescript/tests/query/expr.spec.ts @@ -9,46 +9,24 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/expr/#compare-two-fields-from-a-single-document} */ function test0() { - type monthlyBudget = { - _id: number; - category: string; - budget: number; - spent: number; + type TestCollection = { + title: string; + tomatoes: { + viewer: { + rating: number; + }; + }; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $match: { $expr: { $gt: ['$spent', '$budget'] } } }, ]; } /** * Using $expr With Conditional Statements - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/expr/#use--expr-with-conditional-statements} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/expr/#using--expr-with-conditional-statements} */ function test1() { - type supplies = { - _id: number; - item: string; - qty: bson.Int32 | number; - price: bson.Decimal128; - }; - - const aggregation: schema.Pipeline = [ - { - $match: { - $expr: { - $lt: [ - { - $cond: { - if: { $gte: ['$qty', 100] }, - then: { $multiply: ['$price', 0.5] }, - else: { $multiply: ['$price', 0.75] }, - }, - }, - 5, - ], - }, - }, - }, - ]; + // TODO: no schema found for expr.Using $expr With Conditional Statements: // TODO: No schema found in docs } diff --git a/packages/mql-typescript/tests/query/gt.spec.ts b/packages/mql-typescript/tests/query/gt.spec.ts index 4b98bdea..4b03c166 100644 --- a/packages/mql-typescript/tests/query/gt.spec.ts +++ b/packages/mql-typescript/tests/query/gt.spec.ts @@ -10,15 +10,14 @@ import * as bson from 'bson'; */ function test0() { type inventory = { - item: string; - quantity: number; - carrier: { - name: string; - fee: number; - }; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; + tags: Array; }; const aggregation: schema.Pipeline = [ - { $match: { quantity: { $gt: 20 } } }, + { $match: { qty: { $gt: 20 } } }, ]; } diff --git a/packages/mql-typescript/tests/query/gte.spec.ts b/packages/mql-typescript/tests/query/gte.spec.ts index 451d8586..15369829 100644 --- a/packages/mql-typescript/tests/query/gte.spec.ts +++ b/packages/mql-typescript/tests/query/gte.spec.ts @@ -10,15 +10,14 @@ import * as bson from 'bson'; */ function test0() { type inventory = { - item: string; - quantity: number; - carrier: { - name: string; - fee: number; - }; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; + tags: Array; }; const aggregation: schema.Pipeline = [ - { $match: { quantity: { $gte: 20 } } }, + { $match: { qty: { $gte: 20 } } }, ]; } diff --git a/packages/mql-typescript/tests/query/in.spec.ts b/packages/mql-typescript/tests/query/in.spec.ts index 159ca727..1cdf5417 100644 --- a/packages/mql-typescript/tests/query/in.spec.ts +++ b/packages/mql-typescript/tests/query/in.spec.ts @@ -9,15 +9,7 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/in/#use-the--in-operator-to-match-values} */ function test0() { - type inventory = { - item: string; - quantity: number; - tags: Array; - }; - - const aggregation: schema.Pipeline = [ - { $match: { tags: { $in: ['home', 'school'] } } }, - ]; + // TODO: no schema found for in.Use the $in Operator to Match Values in an Array } /** @@ -25,19 +17,5 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/in/#use-the--in-operator-with-a-regular-expression} */ function test1() { - type inventory = { - item: string; - quantity: number; - tags: Array; - }; - - const aggregation: schema.Pipeline = [ - { - $match: { - tags: { - $in: [new bson.BSONRegExp('^be', ''), new bson.BSONRegExp('^st', '')], - }, - }, - }, - ]; + // TODO: no schema found for in.Use the $in Operator with a Regular Expression } diff --git a/packages/mql-typescript/tests/query/lt.spec.ts b/packages/mql-typescript/tests/query/lt.spec.ts index 64635dd6..112f5502 100644 --- a/packages/mql-typescript/tests/query/lt.spec.ts +++ b/packages/mql-typescript/tests/query/lt.spec.ts @@ -10,15 +10,14 @@ import * as bson from 'bson'; */ function test0() { type inventory = { - item: string; - quantity: number; - carrier: { - name: string; - fee: number; - }; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; + tags: Array; }; const aggregation: schema.Pipeline = [ - { $match: { quantity: { $lt: 20 } } }, + { $match: { qty: { $lt: 20 } } }, ]; } diff --git a/packages/mql-typescript/tests/query/lte.spec.ts b/packages/mql-typescript/tests/query/lte.spec.ts index 9756f5dd..88f05277 100644 --- a/packages/mql-typescript/tests/query/lte.spec.ts +++ b/packages/mql-typescript/tests/query/lte.spec.ts @@ -10,15 +10,14 @@ import * as bson from 'bson'; */ function test0() { type inventory = { - item: string; - quantity: number; - carrier: { - name: string; - fee: number; - }; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; + tags: Array; }; const aggregation: schema.Pipeline = [ - { $match: { quantity: { $lte: 20 } } }, + { $match: { qty: { $lte: 20 } } }, ]; } diff --git a/packages/mql-typescript/tests/query/ne.spec.ts b/packages/mql-typescript/tests/query/ne.spec.ts index c58c2f25..06577311 100644 --- a/packages/mql-typescript/tests/query/ne.spec.ts +++ b/packages/mql-typescript/tests/query/ne.spec.ts @@ -6,19 +6,8 @@ import * as bson from 'bson'; /** * Match Document Fields - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/ne/#match-document-fields-that-are-not-equal} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/ne/#match-document-fields} */ function test0() { - type inventory = { - item: string; - quantity: number; - carrier: { - name: string; - fee: number; - }; - }; - - const aggregation: schema.Pipeline = [ - { $match: { quantity: { $ne: 20 } } }, - ]; + // TODO: no schema found for ne.Match Document Fields } diff --git a/packages/mql-typescript/tests/query/nin.spec.ts b/packages/mql-typescript/tests/query/nin.spec.ts index 346da259..bb590c7b 100644 --- a/packages/mql-typescript/tests/query/nin.spec.ts +++ b/packages/mql-typescript/tests/query/nin.spec.ts @@ -10,8 +10,10 @@ import * as bson from 'bson'; */ function test0() { type inventory = { - item: string; - quantity: number; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; tags: Array; }; @@ -26,8 +28,10 @@ function test0() { */ function test1() { type inventory = { - item: string; - quantity: number; + price: bson.Double | number; + qty: bson.Int32 | number | undefined; + quantity: bson.Int32 | number | undefined; + sale: boolean; tags: Array; }; diff --git a/packages/mql-typescript/tests/query/not.spec.ts b/packages/mql-typescript/tests/query/not.spec.ts index d27cf7be..83ac674f 100644 --- a/packages/mql-typescript/tests/query/not.spec.ts +++ b/packages/mql-typescript/tests/query/not.spec.ts @@ -24,7 +24,7 @@ function test0() { /** * Regular Expressions - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/not/#regular-expressions} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/not/#-not-and-regular-expressions} */ function test1() { type inventory = { diff --git a/packages/mql-typescript/tests/query/rand.spec.ts b/packages/mql-typescript/tests/query/rand.spec.ts index 72b590fe..0698736e 100644 --- a/packages/mql-typescript/tests/query/rand.spec.ts +++ b/packages/mql-typescript/tests/query/rand.spec.ts @@ -9,15 +9,5 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/rand/#select-random-items-from-a-collection} */ function test0() { - type voters = { - name: string; - voterId: number; - district: number; - registered: boolean; - }; - - const aggregation: schema.Pipeline = [ - { $match: { district: 3, $expr: { $lt: [0.5, { $rand: {} }] } } }, - { $project: { _id: 0, name: 1, registered: 1 } }, - ]; + // TODO: no schema found for rand.Select Random Items From a Collection } diff --git a/packages/mql-typescript/tests/query/text.spec.ts b/packages/mql-typescript/tests/query/text.spec.ts index 88f612c0..6ba3ae50 100644 --- a/packages/mql-typescript/tests/query/text.spec.ts +++ b/packages/mql-typescript/tests/query/text.spec.ts @@ -6,110 +6,56 @@ import * as bson from 'bson'; /** * Search for a Single Word - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#-text-with-a-single-word} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-for-a-single-word} */ function test0() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'coffee' } } }, - ]; + // TODO: no schema found for text.Search for a Single Word } /** - * Query a Different Language - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#query-a-different-language} + * Match Any of the Search Terms + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-for-a-single-word} */ function test1() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'leche', $language: 'es' } } }, - ]; + // TODO: no schema found for text.Match Any of the Search Terms } /** - * Case and Diacritic Insensitive Search - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#case-and-diacritic-insensitivity} + * Search a Different Language + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#search-a-different-language} */ function test2() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'сы́рники CAFÉS' } } }, - ]; + // TODO: no schema found for text.Search a Different Language } /** - * Perform Case Sensitive Search - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#case-sensitivity} + * Case and Diacritic Insensitive Search + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#case-and-diacritic-insensitive-search} */ function test3() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'Coffee', $caseSensitive: true } } }, - { - $match: { - $text: { $search: '\\"Café Con Leche\\"', $caseSensitive: true }, - }, - }, - ]; + // TODO: no schema found for text.Case and Diacritic Insensitive Search } /** - * Diacritic Sensitive Search - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#diacritic-sensitivity} + * Perform Case Sensitive Search + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search} */ function test4() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'CAFÉ', $diacriticSensitive: true } } }, - ]; + // TODO: no schema found for text.Perform Case Sensitive Search } /** - * Text Search Score Examples - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#relevance-score-examples} + * Diacritic Sensitive Search + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search} */ function test5() { - type articles = { - _id: number; - subject: string; - author: string; - views: number; - }; + // TODO: no schema found for text.Diacritic Sensitive Search +} - const aggregation: schema.Pipeline = [ - { $match: { $text: { $search: 'CAFÉ', $diacriticSensitive: true } } }, - { $project: { score: { $meta: 'textScore' } } }, - { $sort: { score: { $meta: 'textScore' } } }, - { $limit: 5 }, - ]; +/** + * Text Search Score Examples + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/text/#perform-case-sensitive-search} + */ +function test6() { + // TODO: no schema found for text.Text Search Score Examples } diff --git a/packages/mql-typescript/tests/query/type.spec.ts b/packages/mql-typescript/tests/query/type.spec.ts index be8ce6ec..91c08d80 100644 --- a/packages/mql-typescript/tests/query/type.spec.ts +++ b/packages/mql-typescript/tests/query/type.spec.ts @@ -10,9 +10,15 @@ import * as bson from 'bson'; */ function test0() { type addressBook = { - _id: number; + _id: bson.Int32 | number; address: string; - zipCode: string | number | bson.Long | bson.Int32 | number | Array; + zipCode: + | string + | bson.Int32 + | number + | bson.Double + | number + | Array; }; const aggregation: schema.Pipeline = [ @@ -26,19 +32,10 @@ function test0() { /** * Querying by Multiple Data Type - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/type/#querying-by-multiple-data-types} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/type/#querying-by-multiple-data-type} */ function test1() { - type grades = { - _id: number; - name: string; - classAverage: string | number | bson.Int32 | number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { classAverage: { $type: [2, 1] } } }, - { $match: { classAverage: { $type: ['string', 'double'] } } }, - ]; + // TODO: no schema found for type.Querying by Multiple Data Type: // TODO: No schema found in docs } /** @@ -83,12 +80,19 @@ function test2() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/query/type/#querying-by-array-type} */ function test3() { - type sensorReading = { - _id: number; - readings: Array> | number; + type addressBook = { + _id: bson.Int32 | number; + address: string; + zipCode: + | string + | bson.Int32 + | number + | bson.Double + | number + | Array; }; - const aggregation: schema.Pipeline = [ - { $match: { readings: { $type: ['array'] } } }, + const aggregation: schema.Pipeline = [ + { $match: { zipCode: { $type: ['array'] } } }, ]; } diff --git a/packages/mql-typescript/tests/search/facet.spec.ts b/packages/mql-typescript/tests/search/facet.spec.ts index 0d3fa1b2..48a9087e 100644 --- a/packages/mql-typescript/tests/search/facet.spec.ts +++ b/packages/mql-typescript/tests/search/facet.spec.ts @@ -98,3 +98,191 @@ function test0() { { $set: { meta: { $arrayElemAt: ['$meta', 0] } } } as any, ]; } + +/** + * Multi-Select Faceting Example + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/facet/#multi-select-faceting-example} + */ +function test1() { + type movies = { + _id: { + $oid: string; + }; + title: string; + year: { + $numberInt: string; + }; + runtime: { + $numberInt: string; + }; + released: { + $date: { + $numberLong: string; + }; + }; + poster: string; + plot: string; + fullplot: string; + lastupdated: string; + type: string; + directors: Array; + imdb: { + rating: { + $numberDouble: string; + }; + votes: { + $numberInt: string; + }; + id: { + $numberInt: string; + }; + }; + cast: Array; + countries: Array; + genres: Array; + tomatoes: { + viewer: { + rating: { + $numberDouble: string; + }; + numReviews: { + $numberInt: string; + }; + }; + lastUpdated: { + $date: { + $numberLong: string; + }; + }; + }; + num_mflix_comments: { + $numberInt: string; + }; + }; + + const aggregation: schema.Pipeline = [ + { + $searchMeta: { + facet: { + operator: { + compound: { + must: [{ text: { path: 'description', query: 'new york city' } }], + filter: [ + { + equals: { + path: 'cancellation_policy', + value: 'moderate', + doesNotAffect: 'cancellationFacet', + }, + }, + ], + }, + }, + facets: { + accommodatesFacet: { + path: 'accommodates', + type: 'number', + boundaries: [1, 2, 4, 8], + }, + cancellationFacet: { path: 'cancellation_policy', type: 'string' }, + roomTypeFacet: { path: 'room_type', type: 'string' }, + }, + }, + }, + }, + ]; +} + +/** + * Inter-Facet Filter Exclusion Example + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/facet/#inter-facet-filter-exclusion-example} + */ +function test2() { + type movies = { + _id: { + $oid: string; + }; + title: string; + year: { + $numberInt: string; + }; + runtime: { + $numberInt: string; + }; + released: { + $date: { + $numberLong: string; + }; + }; + poster: string; + plot: string; + fullplot: string; + lastupdated: string; + type: string; + directors: Array; + imdb: { + rating: { + $numberDouble: string; + }; + votes: { + $numberInt: string; + }; + id: { + $numberInt: string; + }; + }; + cast: Array; + countries: Array; + genres: Array; + tomatoes: { + viewer: { + rating: { + $numberDouble: string; + }; + numReviews: { + $numberInt: string; + }; + }; + lastUpdated: { + $date: { + $numberLong: string; + }; + }; + }; + num_mflix_comments: { + $numberInt: string; + }; + }; + + const aggregation: schema.Pipeline = [ + { + $searchMeta: { + facet: { + operator: { + compound: { + must: [{ text: { path: 'description', query: 'new york city' } }], + filter: [ + { + equals: { + path: 'cancellation_policy', + value: 'moderate', + doesNotAffect: 'accommodatesFacet', + }, + }, + ], + }, + }, + facets: { + accommodatesFacet: { + path: 'accommodates', + type: 'number', + boundaries: [1, 2, 4, 8], + }, + cancellationFacet: { path: 'cancellation_policy', type: 'string' }, + roomTypeFacet: { path: 'room_type', type: 'string' }, + }, + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/search/hasAncestor.spec.ts b/packages/mql-typescript/tests/search/hasAncestor.spec.ts new file mode 100644 index 00000000..af9cbb21 --- /dev/null +++ b/packages/mql-typescript/tests/search/hasAncestor.spec.ts @@ -0,0 +1,50 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasAncestor/#sample-query} + */ +function test0() { + type TestCollection = { + mappings: { + dynamic: boolean; + fields: { + funding_rounds: { + dynamic: boolean; + fields: { + investments: Array<{ + dynamic: boolean; + storedSource: { + include: Array; + }; + type: string; + }>; + }; + type: string; + }; + }; + }; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $search: { + returnStoredSource: true, + returnScope: { path: 'funding_rounds.investments' }, + hasAncestor: { + ancestorPath: 'funding_rounds', + operator: { + equals: { path: 'funding_rounds.funded_year', value: 2005 }, + }, + }, + }, + } as any, + ]; +} diff --git a/packages/mql-typescript/tests/search/hasRoot.spec.ts b/packages/mql-typescript/tests/search/hasRoot.spec.ts new file mode 100644 index 00000000..60e74330 --- /dev/null +++ b/packages/mql-typescript/tests/search/hasRoot.spec.ts @@ -0,0 +1,179 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Simple Query + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasRoot/#simple-query} + */ +function test0() { + type TestCollection = { + mappings: { + dynamic: boolean; + fields: { + funding_rounds: { + dynamic: boolean; + fields: { + investments: Array<{ + dynamic: boolean; + type: string; + }>; + }; + storedSource: { + include: Array; + }; + type: string; + }; + products: { + dynamic: boolean; + storedSource: { + include: Array; + }; + type: string; + }; + }; + }; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $search: { + returnStoredSource: true, + returnScope: { path: 'products' }, + hasRoot: { + operator: { range: { path: 'founded_year', gte: 2005, lte: 2010 } }, + }, + }, + } as any, + ]; +} + +/** + * Multi-Level Query + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasRoot/#multi-level-query} + */ +function test1() { + type TestCollection = { + mappings: { + dynamic: boolean; + fields: { + funding_rounds: { + dynamic: boolean; + fields: { + investments: Array<{ + dynamic: boolean; + type: string; + }>; + }; + storedSource: { + include: Array; + }; + type: string; + }; + products: { + dynamic: boolean; + storedSource: { + include: Array; + }; + type: string; + }; + }; + }; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $search: { + returnStoredSource: true, + returnScope: { path: 'funding_rounds' }, + hasRoot: { operator: { text: { path: 'name', query: 'Facebook' } } }, + }, + } as any, + ]; +} + +/** + * Compound Query + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/operators-collectors/hasRoot/#compound-query} + */ +function test2() { + type TestCollection = { + mappings: { + dynamic: boolean; + fields: { + funding_rounds: { + dynamic: boolean; + fields: { + investments: Array<{ + dynamic: boolean; + type: string; + }>; + }; + storedSource: { + include: Array; + }; + type: string; + }; + products: { + dynamic: boolean; + storedSource: { + include: Array; + }; + type: string; + }; + }; + }; + }; + + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { + $search: { + compound: { + should: [ + { + embeddedDocument: { + path: 'funding_rounds.investments', + operator: { + wildcard: { + path: 'funding_rounds.investments.financial_org.name', + query: '*Ventures*', + allowAnalyzedField: true, + }, + }, + }, + }, + { + hasRoot: { + operator: { + wildcard: { + path: 'description', + query: '*network*', + allowAnalyzedField: true, + }, + }, + }, + }, + ], + }, + returnScope: { path: 'funding_rounds' }, + returnStoredSource: true, + }, + } as any, + + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (this test accesses nested fields, which is not currently supported). + */ + { $limit: 5 } as any, + ]; +} diff --git a/packages/mql-typescript/tests/search/vectorSearch.spec.ts b/packages/mql-typescript/tests/search/vectorSearch.spec.ts new file mode 100644 index 00000000..2c0d8800 --- /dev/null +++ b/packages/mql-typescript/tests/search/vectorSearch.spec.ts @@ -0,0 +1,97 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * ANN Basic + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/vector-search/#basic-example} + */ +function test0() { + type movies = { + plot_embedding: Array; + plot: string; + title: string; + }; + + const aggregation: schema.Pipeline = [ + { + $search: { + vectorSearch: { + path: 'plot_embedding', + queryVector: [-0.0016261312, -0.028070757, -0.011342932], + numCandidates: 150, + limit: 10, + }, + }, + }, + { + $project: { _id: 0, plot: 1, title: 1, score: { $meta: 'searchScore' } }, + }, + ]; +} + +/** + * ANN Filter + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/vector-search/#filter-example} + */ +function test1() { + type movies = { + plot_embedding: Array; + year: bson.Int32 | number; + plot: string; + title: string; + }; + + const aggregation: schema.Pipeline = [ + { + $search: { + vectorSearch: { + path: 'plot_embedding', + queryVector: [0.02421053, -0.022372592, -0.006231137], + filter: { range: { path: 'year', lt: 1975 } }, + numCandidates: 150, + limit: 10, + }, + }, + }, + { + $project: { + _id: 0, + title: 1, + plot: 1, + year: 1, + score: { $meta: 'searchScore' }, + }, + }, + ]; +} + +/** + * ENN + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/vector-search/#enn-example} + */ +function test2() { + type movies = { + plot_embedding: Array; + plot: string; + title: string; + }; + + const aggregation: schema.Pipeline = [ + { + $search: { + vectorSearch: { + path: 'plot_embedding', + queryVector: [-0.006954097, -0.009932499, -0.001311474], + exact: true, + limit: 10, + }, + }, + }, + { + $project: { _id: 0, plot: 1, title: 1, score: { $meta: 'searchScore' } }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/stage/addFields.spec.ts b/packages/mql-typescript/tests/stage/addFields.spec.ts index 969b5d22..e3cc878c 100644 --- a/packages/mql-typescript/tests/stage/addFields.spec.ts +++ b/packages/mql-typescript/tests/stage/addFields.spec.ts @@ -9,31 +9,7 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/#using-two--addfields-stages} */ function test0() { - type scores = { - _id: number; - student: string; - homework: Array; - quiz: Array; - extraCredit: number; - }; - - const aggregation: schema.Pipeline = [ - { - $addFields: { - totalHomework: { $sum: ['$homework'] }, - totalQuiz: { $sum: ['$quiz'] }, - }, - }, - - /** - * This stage is unsupported by the static type system, so we're casting it to 'any' (it may involve a projected field). - */ - { - $addFields: { - totalScore: { $add: ['$totalHomework', '$totalQuiz', '$extraCredit'] }, - }, - } as any, - ]; + // TODO: no schema found for addFields.Using Two $addFields Stages } /** @@ -41,18 +17,7 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/#adding-fields-to-an-embedded-document} */ function test1() { - type vehicles = { - _id: number; - type: string; - specs: { - doors: number; - wheels: number; - }; - }; - - const aggregation: schema.Pipeline = [ - { $addFields: { 'specs.fuel_type': 'unleaded' } }, - ]; + // TODO: no schema found for addFields.Adding Fields to an Embedded Document } /** @@ -60,13 +25,7 @@ function test1() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/#overwriting-an-existing-field} */ function test2() { - type animals = { - _id: number; - dogs: number; - cats: number; - }; - - const aggregation: schema.Pipeline = [{ $addFields: { cats: 20 } }]; + // TODO: no schema found for addFields.Overwriting an existing field } /** @@ -74,16 +33,5 @@ function test2() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/addFields/#add-element-to-an-array} */ function test3() { - type scores = { - _id: number; - student: string; - homework: Array; - quiz: Array; - extraCredit: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { _id: 1 } }, - { $addFields: { homework: { $concatArrays: ['$homework', [7]] } } }, - ]; + // TODO: no schema found for addFields.Add Element to an Array } diff --git a/packages/mql-typescript/tests/stage/count.spec.ts b/packages/mql-typescript/tests/stage/count.spec.ts index d5f9e9d4..10488111 100644 --- a/packages/mql-typescript/tests/stage/count.spec.ts +++ b/packages/mql-typescript/tests/stage/count.spec.ts @@ -6,17 +6,8 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/count/#examples} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/count/#example} */ function test0() { - type scores = { - _id: number; - subject: string; - score: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { score: { $gt: 80 } } }, - { $count: 'passing_scores' }, - ]; + // TODO: no schema found for count.Example } diff --git a/packages/mql-typescript/tests/stage/densify.spec.ts b/packages/mql-typescript/tests/stage/densify.spec.ts index d603a75c..1b104a05 100644 --- a/packages/mql-typescript/tests/stage/densify.spec.ts +++ b/packages/mql-typescript/tests/stage/densify.spec.ts @@ -37,23 +37,8 @@ function test0() { /** * Densifiction with Partitions - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/#densification-with-partitions} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify/#densifiction-with-partitions} */ function test1() { - type coffee = { - altitude: number; - variety: string; - score: number; - price: number; - }; - - const aggregation: schema.Pipeline = [ - { - $densify: { - field: 'altitude', - partitionByFields: ['variety'], - range: { bounds: 'full', step: 200 }, - }, - }, - ]; + // TODO: no schema found for densify.Densifiction with Partitions: // TODO: No schema found in docs } diff --git a/packages/mql-typescript/tests/stage/facet.spec.ts b/packages/mql-typescript/tests/stage/facet.spec.ts index 0c6eddf8..af4a475e 100644 --- a/packages/mql-typescript/tests/stage/facet.spec.ts +++ b/packages/mql-typescript/tests/stage/facet.spec.ts @@ -9,37 +9,5 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/facet/#example} */ function test0() { - type artwork = { - _id: number; - title: string; - artist: string; - year: number; - price: bson.Decimal128; - tags: Array; - }; - - const aggregation: schema.Pipeline = [ - { - $facet: { - categorizedByTags: [ - { $unwind: { path: '$tags' } }, - { $sortByCount: '$tags' }, - ], - categorizedByPrice: [ - { $match: { price: { $exists: true } } }, - { - $bucket: { - groupBy: '$price', - boundaries: [0, 150, 200, 300, 400], - default: 'Other', - output: { count: { $sum: 1 }, titles: { $push: '$title' } }, - }, - }, - ], - 'categorizedByYears(Auto)': [ - { $bucketAuto: { groupBy: '$year', buckets: 4 } }, - ], - }, - }, - ]; + // TODO: no schema found for facet.Example } diff --git a/packages/mql-typescript/tests/stage/group.spec.ts b/packages/mql-typescript/tests/stage/group.spec.ts index 8bccbcc5..9770eca0 100644 --- a/packages/mql-typescript/tests/stage/group.spec.ts +++ b/packages/mql-typescript/tests/stage/group.spec.ts @@ -9,15 +9,12 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#count-the-number-of-documents-in-a-collection} */ function test0() { - type sales = { - _id: number; - item: string; - price: bson.Decimal128; - quantity: bson.Int32 | number; - date: Date; + type TestCollection = { + _id: null; + count: number; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $group: { _id: null, count: { $count: {} } } }, ]; } @@ -27,15 +24,14 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#retrieve-distinct-values} */ function test1() { - type sales = { - _id: number; - item: string; - price: bson.Decimal128; - quantity: bson.Int32 | number; - date: Date; + type TestCollection = { + _id: null; + count: number; }; - const aggregation: schema.Pipeline = [{ $group: { _id: '$item' } }]; + const aggregation: schema.Pipeline = [ + { $group: { _id: '$item' } }, + ]; } /** @@ -43,27 +39,7 @@ function test1() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#group-by-item-having} */ function test2() { - type sales = { - _id: number; - item: string; - price: bson.Decimal128; - quantity: bson.Int32 | number; - date: Date; - }; - - const aggregation: schema.Pipeline = [ - { - $group: { - _id: '$item', - totalSaleAmount: { $sum: { $multiply: ['$price', '$quantity'] } }, - }, - }, - - /** - * This stage is unsupported by the static type system, so we're casting it to 'any' (it may involve a projected field). - */ - { $match: { totalSaleAmount: { $gte: 100 } } } as any, - ]; + // TODO: no schema found for group.Group by Item Having: // TODO: No schema found in docs } /** @@ -72,7 +48,7 @@ function test2() { */ function test3() { type sales = { - _id: number; + _id: bson.Int32 | number; item: string; price: bson.Decimal128; quantity: bson.Int32 | number; @@ -106,7 +82,7 @@ function test3() { */ function test4() { type sales = { - _id: number; + _id: bson.Int32 | number; item: string; price: bson.Decimal128; quantity: bson.Int32 | number; @@ -130,14 +106,12 @@ function test4() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#pivot-data} */ function test5() { - type books = { - _id: number; - title: string; - author: string; - copies: number; + type TestCollection = { + _id: null; + count: number; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $group: { _id: '$author', books: { $push: '$title' } } }, ]; } @@ -147,20 +121,5 @@ function test5() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/group/#group-documents-by-author} */ function test6() { - type sales = { - _id: number; - item: string; - price: bson.Decimal128; - quantity: bson.Int32 | number; - date: Date; - }; - - const aggregation: schema.Pipeline = [ - { $group: { _id: '$author', books: { $push: '$$ROOT' } } }, - - /** - * This stage is unsupported by the static type system, so we're casting it to 'any' (it may involve a projected field). - */ - { $addFields: { totalCopies: { $sum: ['$books.copies'] } } } as any, - ]; + // TODO: no schema found for group.Group Documents by author: // TODO: No schema found in docs } diff --git a/packages/mql-typescript/tests/stage/indexStats.spec.ts b/packages/mql-typescript/tests/stage/indexStats.spec.ts index c61d65c2..469b08e4 100644 --- a/packages/mql-typescript/tests/stage/indexStats.spec.ts +++ b/packages/mql-typescript/tests/stage/indexStats.spec.ts @@ -9,13 +9,5 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/indexStats/#example} */ function test0() { - type orders = { - _id: number; - item: string; - price: number; - quantity: number; - type: string; - }; - - const aggregation: schema.Pipeline = [{ $indexStats: {} }]; + // TODO: no schema found for indexStats.Example } diff --git a/packages/mql-typescript/tests/stage/lookup.spec.ts b/packages/mql-typescript/tests/stage/lookup.spec.ts index 580ce1d2..0198eb0d 100644 --- a/packages/mql-typescript/tests/stage/lookup.spec.ts +++ b/packages/mql-typescript/tests/stage/lookup.spec.ts @@ -9,14 +9,17 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/#perform-a-single-equality-join-with--lookup} */ function test0() { - type orders = { - _id: number; - item: string; - price: number; - quantity: number; + type TestCollection = { + title: string; + year: number; + movie_comments: Array<{ + name: string; + text: string; + date: Date; + }>; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $lookup: { from: 'inventory', @@ -33,14 +36,17 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/#use--lookup-with-an-array} */ function test1() { - type classes = { - _id: number; + type TestCollection = { title: string; - enrollmentlist: Array; - days: Array; + year: number; + movie_comments: Array<{ + name: string; + text: string; + date: Date; + }>; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $lookup: { from: 'members', @@ -57,14 +63,17 @@ function test1() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/#use--lookup-with--mergeobjects} */ function test2() { - type orders = { - _id: number; - item: string; - price: number; - quantity: number; + type TestCollection = { + title: string; + year: number; + movie_comments: Array<{ + name: string; + text: string; + date: Date; + }>; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $lookup: { from: 'items', @@ -97,13 +106,20 @@ function test3() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/#perform-an-uncorrelated-subquery-with--lookup} */ function test4() { - type absences = { - _id: number; - student: string; - sickdays: Array; + type TestCollection = { + title: string; + year: number; + movie_comments: Array<{ + name: string; + text: string; + date: Date; + }>; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (the lookup sub-pipeline references fields from the joined collection that are not available statically). + */ { $lookup: { from: 'holidays', @@ -114,7 +130,7 @@ function test4() { ], as: 'holidays', }, - }, + } as any, ]; } @@ -123,14 +139,20 @@ function test4() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup/#perform-a-concise-correlated-subquery-with--lookup} */ function test5() { - type restaurants = { - _id: number; - name: string; - food: Array; - beverages: Array; + type TestCollection = { + title: string; + year: number; + movie_comments: Array<{ + name: string; + text: string; + date: Date; + }>; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ + /** + * This stage is unsupported by the static type system, so we're casting it to 'any' (the lookup sub-pipeline references the variables defined in the `let` field, which are not available statically). + */ { $lookup: { from: 'restaurants', @@ -142,6 +164,6 @@ function test5() { ], as: 'matches', }, - }, + } as any, ]; } diff --git a/packages/mql-typescript/tests/stage/match.spec.ts b/packages/mql-typescript/tests/stage/match.spec.ts index 040f9ad4..29a079dc 100644 --- a/packages/mql-typescript/tests/stage/match.spec.ts +++ b/packages/mql-typescript/tests/stage/match.spec.ts @@ -9,16 +9,7 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#equality-match} */ function test0() { - type TestCollection = { - _id: bson.ObjectId; - author: string; - score: number; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { author: 'dave' } }, - ]; + // TODO: no schema found for match.Equality Match } /** @@ -26,19 +17,5 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/match/#perform-a-count} */ function test1() { - type TestCollection = { - _id: bson.ObjectId; - author: string; - score: number; - views: number; - }; - - const aggregation: schema.Pipeline = [ - { - $match: { - $or: [{ score: { $gt: 70, $lt: 90 } }, { views: { $gte: 1000 } }], - }, - }, - { $group: { _id: null, count: { $sum: 1 } } }, - ]; + // TODO: no schema found for match.Perform a Count } diff --git a/packages/mql-typescript/tests/stage/merge.spec.ts b/packages/mql-typescript/tests/stage/merge.spec.ts index 4f2cea30..31829993 100644 --- a/packages/mql-typescript/tests/stage/merge.spec.ts +++ b/packages/mql-typescript/tests/stage/merge.spec.ts @@ -9,30 +9,7 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#on-demand-materialized-view--initial-creation} */ function test0() { - type salaries = { - _id: number; - employee: string; - dept: string; - salary: number; - fiscal_year: number; - }; - - const aggregation: schema.Pipeline = [ - { - $group: { - _id: { fiscal_year: '$fiscal_year', dept: '$dept' }, - salaries: { $sum: '$salary' }, - }, - }, - { - $merge: { - into: { db: 'reporting', coll: 'budgets' }, - on: '_id', - whenMatched: 'replace', - whenNotMatched: 'insert', - }, - }, - ]; + // TODO: no schema found for merge.On-Demand Materialized View Initial Creation } /** @@ -40,31 +17,7 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#on-demand-materialized-view--update-replace-data} */ function test1() { - type salaries = { - _id: number; - employee: string; - dept: string; - salary: number; - fiscal_year: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { fiscal_year: { $gte: 2019 } } }, - { - $group: { - _id: { fiscal_year: '$fiscal_year', dept: '$dept' }, - salaries: { $sum: '$salary' }, - }, - }, - { - $merge: { - into: { db: 'reporting', coll: 'budgets' }, - on: '_id', - whenMatched: 'replace', - whenNotMatched: 'insert', - }, - }, - ]; + // TODO: no schema found for merge.On-Demand Materialized View Update Replace Data } /** @@ -72,38 +25,7 @@ function test1() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#only-insert-new-data} */ function test2() { - type salaries = { - _id: number; - employee: string; - dept: string; - salary: number; - fiscal_year: number; - }; - - const aggregation: schema.Pipeline = [ - { $match: { fiscal_year: 2019 } }, - { - $group: { - _id: { fiscal_year: '$fiscal_year', dept: '$dept' }, - employees: { $push: '$employee' }, - }, - }, - { - $project: { - _id: 0, - dept: '$_id.dept', - fiscal_year: '$_id.fiscal_year', - employees: 1, - }, - }, - { - $merge: { - into: { db: 'reporting', coll: 'orgArchive' }, - on: ['dept', 'fiscal_year'], - whenMatched: 'fail', - }, - }, - ]; + // TODO: no schema found for merge.Only Insert New Data } /** @@ -111,25 +33,7 @@ function test2() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#merge-results-from-multiple-collections} */ function test3() { - type purchaseorders = { - _id: number; - quarter: string; - region: string; - qty: number; - reportDate: Date; - }; - - const aggregation: schema.Pipeline = [ - { $group: { _id: '$quarter', purchased: { $sum: '$qty' } } }, - { - $merge: { - into: 'quarterlyreport', - on: '_id', - whenMatched: 'merge', - whenNotMatched: 'insert', - }, - }, - ]; + // TODO: no schema found for merge.Merge Results from Multiple Collections } /** @@ -137,44 +41,7 @@ function test3() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#use-the-pipeline-to-customize-the-merge} */ function test4() { - type votes = { - date: Date; - thumbsup: number; - thumbsdown: number; - }; - - const aggregation: schema.Pipeline = [ - { - $match: { - date: { - $gte: new Date('2019-05-07T00:00:00.000Z'), - $lt: new Date('2019-05-08T00:00:00.000Z'), - }, - }, - }, - { - $project: { - _id: { $dateToString: { format: '%Y-%m', date: '$date' } }, - thumbsup: 1, - thumbsdown: 1, - }, - }, - { - $merge: { - into: 'monthlytotals', - on: '_id', - whenMatched: [ - { - $addFields: { - thumbsup: { $add: ['$thumbsup', '$$new.thumbsup'] }, - thumbsdown: { $add: ['$thumbsdown', '$$new.thumbsdown'] }, - }, - }, - ], - whenNotMatched: 'insert', - }, - }, - ]; + // TODO: no schema found for merge.Use the Pipeline to Customize the Merge } /** @@ -182,21 +49,5 @@ function test4() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/merge/#use-variables-to-customize-the-merge} */ function test5() { - type salaries = { - _id: number; - employee: string; - dept: string; - salary: number; - fiscal_year: number; - }; - - const aggregation: schema.Pipeline = [ - { - $merge: { - into: 'cakeSales', - let: { year: '2020' }, - whenMatched: [{ $addFields: { salesYear: '$$year' } }], - }, - }, - ]; + // TODO: no schema found for merge.Use Variables to Customize the Merge } diff --git a/packages/mql-typescript/tests/stage/out.spec.ts b/packages/mql-typescript/tests/stage/out.spec.ts index 842dac45..1c37201e 100644 --- a/packages/mql-typescript/tests/stage/out.spec.ts +++ b/packages/mql-typescript/tests/stage/out.spec.ts @@ -18,7 +18,7 @@ function test0() { const aggregation: schema.Pipeline = [ { $group: { _id: '$author', books: { $push: '$title' } } }, - { $out: 'authors' }, + { $out: { coll: 'authors' } }, ]; } @@ -39,3 +39,29 @@ function test1() { { $out: { db: 'reporting', coll: 'authors' } }, ]; } + +/** + * Output to a Time Series Collection + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/out/#output-to-a-time-series-collection} + */ +function test2() { + type sensors = { + timestamp: Date; + sensorId: string; + temperature: number; + }; + + const aggregation: schema.Pipeline = [ + { + $out: { + db: 'reporting', + coll: 'sensorData', + timeseries: { + timeField: 'timestamp', + metaField: 'sensorId', + granularity: 'hours', + }, + }, + }, + ]; +} diff --git a/packages/mql-typescript/tests/stage/project.spec.ts b/packages/mql-typescript/tests/stage/project.spec.ts index 4ca4b905..cd22e771 100644 --- a/packages/mql-typescript/tests/stage/project.spec.ts +++ b/packages/mql-typescript/tests/stage/project.spec.ts @@ -9,18 +9,13 @@ import * as bson from 'bson'; * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#include-specific-fields-in-output-documents} */ function test0() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - }; - copies: number; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { title: 1, author: 1 } }, ]; } @@ -30,18 +25,13 @@ function test0() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#suppress-_id-field-in-the-output-documents} */ function test1() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - }; - copies: number; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { _id: 0, title: 1, author: 1 } }, ]; } @@ -51,19 +41,13 @@ function test1() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#exclude-fields-from-output-documents} */ function test2() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - }; - copies: number; - lastModified: string; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { lastModified: 0 } }, ]; } @@ -73,19 +57,13 @@ function test2() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#exclude-fields-from-embedded-documents} */ function test3() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - }; - copies: number; - lastModified: string; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { 'author.first': 0, lastModified: 0 } }, { $project: { author: { first: 0 }, lastModified: 0 } }, ]; @@ -96,20 +74,13 @@ function test3() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#conditionally-exclude-fields} */ function test4() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - middle: string; - }; - copies: number; - lastModified: string; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { title: 1, @@ -132,23 +103,13 @@ function test4() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#include-specific-fields-from-embedded-documents} */ function test5() { - type bookmarks = { - _id: number; - user: string; - stop: - | { - title: string; - author: string; - page: number; - } - | Array<{ - title: string; - author: string; - page: number; - }>; + type TestCollection = { + _id: bson.ObjectId; + title: string; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { 'stop.title': 1 } }, { $project: { stop: { title: 1 } } }, ]; @@ -159,18 +120,13 @@ function test5() { * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/project/#include-computed-fields} */ function test6() { - type books = { - _id: number; + type TestCollection = { + _id: bson.ObjectId; title: string; - isbn: string; - author: { - last: string; - first: string; - }; - copies: number; + rated: string; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $project: { title: 1, @@ -195,8 +151,8 @@ function test6() { function test7() { type TestCollection = { _id: bson.ObjectId; - x: number; - y: number; + x: bson.Int32 | number; + y: bson.Int32 | number; }; const aggregation: schema.Pipeline = [ diff --git a/packages/mql-typescript/tests/stage/rankFusion.spec.ts b/packages/mql-typescript/tests/stage/rankFusion.spec.ts new file mode 100644 index 00000000..7b8b64ea --- /dev/null +++ b/packages/mql-typescript/tests/stage/rankFusion.spec.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/rankFusion/#examples} + */ +function test0() { + // TODO: no schema found for rankFusion.Example +} diff --git a/packages/mql-typescript/tests/stage/rerank.spec.ts b/packages/mql-typescript/tests/stage/rerank.spec.ts new file mode 100644 index 00000000..84aad1c7 --- /dev/null +++ b/packages/mql-typescript/tests/stage/rerank.spec.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/vector-search/query/aggregation-stages/rerank/#examples} + */ +function test0() { + // TODO: no schema found for rerank.Example +} diff --git a/packages/mql-typescript/tests/stage/sample.spec.ts b/packages/mql-typescript/tests/stage/sample.spec.ts index bfe00b5a..f9f2c19b 100644 --- a/packages/mql-typescript/tests/stage/sample.spec.ts +++ b/packages/mql-typescript/tests/stage/sample.spec.ts @@ -6,15 +6,8 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/#examples} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sample/#example} */ function test0() { - type users = { - _id: number; - name: string; - q1: boolean; - q2: boolean; - }; - - const aggregation: schema.Pipeline = [{ $sample: { size: 3 } }]; + // TODO: no schema found for sample.Example } diff --git a/packages/mql-typescript/tests/stage/score.spec.ts b/packages/mql-typescript/tests/stage/score.spec.ts new file mode 100644 index 00000000..cf64c514 --- /dev/null +++ b/packages/mql-typescript/tests/stage/score.spec.ts @@ -0,0 +1,19 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/score/} + */ +function test0() { + type movies = { + plot_embedding: Array; + }; + + const aggregation: schema.Pipeline = [ + { $score: { score: { $meta: 'vectorSearchScore' } } }, + ]; +} diff --git a/packages/mql-typescript/tests/stage/scoreFusion.spec.ts b/packages/mql-typescript/tests/stage/scoreFusion.spec.ts new file mode 100644 index 00000000..e25c9951 --- /dev/null +++ b/packages/mql-typescript/tests/stage/scoreFusion.spec.ts @@ -0,0 +1,13 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +/* eslint-disable filename-rules/match */ +/* eslint-disable @typescript-eslint/consistent-type-imports */ +import type * as schema from '../../out/schema'; +import * as bson from 'bson'; + +/** + * Example + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/scoreFusion/#examples} + */ +function test0() { + // TODO: no schema found for scoreFusion.Example +} diff --git a/packages/mql-typescript/tests/stage/search.spec.ts b/packages/mql-typescript/tests/stage/search.spec.ts index 000b14b4..c2e11bcc 100644 --- a/packages/mql-typescript/tests/stage/search.spec.ts +++ b/packages/mql-typescript/tests/stage/search.spec.ts @@ -6,7 +6,7 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/aggregation-stages/search/#aggregation-variable} + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/query-syntax/#aggregation-variable} */ function test0() { type movies = { diff --git a/packages/mql-typescript/tests/stage/searchMeta.spec.ts b/packages/mql-typescript/tests/stage/searchMeta.spec.ts index cc3e598d..cb0a44a5 100644 --- a/packages/mql-typescript/tests/stage/searchMeta.spec.ts +++ b/packages/mql-typescript/tests/stage/searchMeta.spec.ts @@ -6,7 +6,7 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/aggregation-stages/searchMeta/#example} + * @see {@link https://www.mongodb.com/docs/atlas/atlas-search/query-syntax/#example} */ function test0() { type movies = { diff --git a/packages/mql-typescript/tests/stage/set.spec.ts b/packages/mql-typescript/tests/stage/set.spec.ts index 2f56605d..a45b9c34 100644 --- a/packages/mql-typescript/tests/stage/set.spec.ts +++ b/packages/mql-typescript/tests/stage/set.spec.ts @@ -102,6 +102,6 @@ function test4() { }; const aggregation: schema.Pipeline = [ - { $set: { quizAverage: { $avg: '$quiz' } } }, + { $set: { quizAverage: { $avg: ['$quiz'] } } }, ]; } diff --git a/packages/mql-typescript/tests/stage/skip.spec.ts b/packages/mql-typescript/tests/stage/skip.spec.ts index 12e7e5b5..fd3291eb 100644 --- a/packages/mql-typescript/tests/stage/skip.spec.ts +++ b/packages/mql-typescript/tests/stage/skip.spec.ts @@ -6,7 +6,7 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/#examples} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/skip/#example} */ function test0() { type TestCollection = { diff --git a/packages/mql-typescript/tests/stage/sortByCount.spec.ts b/packages/mql-typescript/tests/stage/sortByCount.spec.ts index d8fe9ac8..612c91e3 100644 --- a/packages/mql-typescript/tests/stage/sortByCount.spec.ts +++ b/packages/mql-typescript/tests/stage/sortByCount.spec.ts @@ -6,19 +6,8 @@ import * as bson from 'bson'; /** * Example - * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/#examples} + * @see {@link https://www.mongodb.com/docs/manual/reference/operator/aggregation/sortByCount/#example} */ function test0() { - type exhibits = { - _id: number; - title: string; - artist: string; - year: number; - tags: Array; - }; - - const aggregation: schema.Pipeline = [ - { $unwind: { path: '$tags' } }, - { $sortByCount: '$tags' }, - ]; + // TODO: no schema found for sortByCount.Example } diff --git a/packages/mql-typescript/tests/stage/vectorSearch.spec.ts b/packages/mql-typescript/tests/stage/vectorSearch.spec.ts index 1234c90c..c3119a7d 100644 --- a/packages/mql-typescript/tests/stage/vectorSearch.spec.ts +++ b/packages/mql-typescript/tests/stage/vectorSearch.spec.ts @@ -6,16 +6,16 @@ import * as bson from 'bson'; /** * ANN Basic - * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#ann-examples} + * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#examples} */ function test0() { - type TestCollection = { + type movies = { + plot_embedding: Array; plot: string; title: string; - score: number; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $vectorSearch: { index: 'vector_index', @@ -38,63 +38,14 @@ function test0() { /** * ANN Filter - * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#ann-examples} + * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#examples} */ function test1() { type movies = { - _id: { - $oid: string; - }; - title: string; - year: { - $numberInt: string; - }; - runtime: { - $numberInt: string; - }; - released: { - $date: { - $numberLong: string; - }; - }; - poster: string; + plot_embedding: Array; + year: bson.Int32 | number; plot: string; - fullplot: string; - lastupdated: string; - type: string; - directors: Array; - imdb: { - rating: { - $numberDouble: string; - }; - votes: { - $numberInt: string; - }; - id: { - $numberInt: string; - }; - }; - cast: Array; - countries: Array; - genres: Array; - tomatoes: { - viewer: { - rating: { - $numberDouble: string; - }; - numReviews: { - $numberInt: string; - }; - }; - lastUpdated: { - $date: { - $numberLong: string; - }; - }; - }; - num_mflix_comments: { - $numberInt: string; - }; + title: string; }; const aggregation: schema.Pipeline = [ @@ -122,16 +73,16 @@ function test1() { /** * ENN - * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#enn-example} + * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#examples} */ function test2() { - type TestCollection = { + type movies = { + plot_embedding: Array; plot: string; title: string; - score: number; }; - const aggregation: schema.Pipeline = [ + const aggregation: schema.Pipeline = [ { $vectorSearch: { index: 'vector_index', @@ -151,3 +102,56 @@ function test2() { }, ]; } + +/** + * Stored Source + * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#examples} + */ +function test3() { + type movies = { + plot_embedding: Array; + year: bson.Int32 | number; + genres: Array; + plot: string; + title: string; + }; + + const aggregation: schema.Pipeline = [ + { + $vectorSearch: { + index: 'vector_index', + path: 'plot_embedding', + queryVector: [ + -0.03994801267981529, -0.016522614285349846, -0.008775344118475914, + ], + filter: { + $and: [ + { year: { $gt: 1970 } }, + { year: { $lt: 2020 } }, + { genres: { $in: ['Action', 'Drama', 'Comedy'] } }, + ], + }, + limit: 10, + numCandidates: 1000, + returnStoredSource: true, + }, + }, + { + $project: { + _id: 0, + plot: 1, + title: 1, + genres: 1, + score: { $meta: 'vectorSearchScore' }, + }, + }, + ]; +} + +/** + * Nested field + * @see {@link https://www.mongodb.com/docs/atlas/atlas-vector-search/vector-search-stage/#examples} + */ +function test4() { + // TODO: no schema found for vectorSearch.Nested field +}