From 9dd43ef57792ca5c420080057ba1bd106457fe06 Mon Sep 17 00:00:00 2001 From: seesharprun Date: Tue, 9 Dec 2025 11:33:04 -0500 Subject: [PATCH] Add reference files --- .../window-operators/$covariancepop.md | 216 +++++++++++++ .../window-operators/$covariancesamp.md | 229 ++++++++++++++ .../operators/window-operators/$denserank.md | 211 +++++++++++++ .../operators/window-operators/$derivative.md | 211 +++++++++++++ .../window-operators/$documentnumber.md | 195 ++++++++++++ .../window-operators/$expmovingavg.md | 285 ++++++++++++++++++ .../operators/window-operators/$integral.md | 218 ++++++++++++++ .../operators/window-operators/$linearfill.md | 194 ++++++++++++ reference/operators/window-operators/$locf.md | 198 ++++++++++++ reference/operators/window-operators/$rank.md | 207 +++++++++++++ .../operators/window-operators/$shift.md | 80 +++++ 11 files changed, 2244 insertions(+) create mode 100644 reference/operators/window-operators/$covariancepop.md create mode 100644 reference/operators/window-operators/$covariancesamp.md create mode 100644 reference/operators/window-operators/$denserank.md create mode 100644 reference/operators/window-operators/$derivative.md create mode 100644 reference/operators/window-operators/$documentnumber.md create mode 100644 reference/operators/window-operators/$expmovingavg.md create mode 100644 reference/operators/window-operators/$integral.md create mode 100644 reference/operators/window-operators/$linearfill.md create mode 100644 reference/operators/window-operators/$locf.md create mode 100644 reference/operators/window-operators/$rank.md create mode 100644 reference/operators/window-operators/$shift.md diff --git a/reference/operators/window-operators/$covariancepop.md b/reference/operators/window-operators/$covariancepop.md new file mode 100644 index 0000000..69bd731 --- /dev/null +++ b/reference/operators/window-operators/$covariancepop.md @@ -0,0 +1,216 @@ +--- +title: $covariancePop +description: The $covariancePop operator returns the covariance of two numerical expressions +type: operators +category: window-operators +--- + +# $covariancePop + +The `$covariancePop` operator sorts documents on one or more fields within a partition and calculates a covariance of two numerical fields within a specified document window. + +## Syntax + +```javascript +{ + $covariancePop: [ < numericalExpression1 > , < numericalExpression2 > ] +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`numericalExpression1`** | The first numerical expression to use to calculate the covariance within the specified document window| +| **`numericalExpression2`** | The first numerical expression to use to calculate the covariance within the specified document window| + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Calculate the covariance in sales volume + +To get the covariance in total sales for stores in the First Up Consultants company, first run a query to filter on the company name, then sort the resulting documents in ascending order of the last updated timestamp, and calculate the covariance between the first and current document in the sorted result set. + +```javascript +db.stores.aggregate( + [{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + } + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "lastUpdated": 1 + }, + "output": { + "covariancePopForSales": { + "$covariancePop": [{ + "$hour": "$lastUpdated" + }, + "$sales.totalSales" + ], + "window": { + "documents": [ + "unbounded", + "current" + ] + } + } + } + } + }, + { + "$project": { + "company": 1, + "name": 1, + "sales.totalSales": 1, + "lastUpdated": 1, + "covariancePopForSales": 1 + } + } + ] +) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "sales": {}, + "company": "First Up Consultants", + "lastUpdated": "2025-06-11T10:48:01.291Z", + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "covariancePopForSales": null + }, + { + "_id": "8e7a259b-f7d6-4ec5-a521-3bed53adc587", + "name": "First Up Consultants | Drone Stop - Lake Joana", + "sales": {}, + "company": "First Up Consultants", + "lastUpdated": { + "t": 1727827539, + "i": 1 + }, + "covariancePopForSales": null + } +] +``` diff --git a/reference/operators/window-operators/$covariancesamp.md b/reference/operators/window-operators/$covariancesamp.md new file mode 100644 index 0000000..baeb20d --- /dev/null +++ b/reference/operators/window-operators/$covariancesamp.md @@ -0,0 +1,229 @@ +--- +title: $covarianceSamp +description: The $covarianceSamp operator returns the covariance of a sample of two numerical expressions +type: operators +category: window-operators +--- + +# $covarianceSamp + +The `$covarianceSamp` operator sorts documents on one or more fields within a partition and calculates the covariance of a sample two numerical fields within a specified document window. + +## Syntax + +```javascript +{ + $covarianceSamp: [ < numericalExpression1 > , < numericalExpression2 > ] +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`numericalExpression1`** | The first numerical expression to use to calculate the covariance sample within the specified document window| +| **`numericalExpression2`** | The first numerical expression to use to calculate the covariance sample within the specified document window| + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Calculate the covariance sample between an unbounded starting document and the current document + +To calculate the covariance sample for stores in the First Up Consultants company, first run a query to filter on the company, then sort the resulting stores in ascending order of their opening dates, and calculate the covariance of the sales of the sorted result set. + +```javascript +db.stores.aggregate( +[{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + }, + "$and": [ + { + "storeOpeningDate": { + "$gt": ISODate("2024-09-01T03:06:24.180Z") + } + }, + { + "storeOpeningDate": { + "$lt": ISODate("2025-09-30T03:55:17.557Z") + } + } + ] + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "storeOpeningDate": 1 + }, + "output": { + "covarianceSampForSales": { + "$covarianceSamp": [ + { + "$hour": "$storeOpeningDate" + }, + "$sales.revenue" + ], + "window": { + "documents": [ + "unbounded", + "current" + ] + } + } + } + } + }, + { + "$project": { + "company": 1, + "name": 1, + "sales.revenue": 1, + "storeOpeningDate": 1, + "covarianceSampForSales": 1 + } + }] +) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "2d315043-db26-4d18-8bb7-71ba922f00a0", + "name": "First Up Consultants | Furniture Shoppe - Wymantown", + "sales": { + "revenue": 38042 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2024-09-02T02:00:52.592Z", + "covarianceSampForSales": 935.0972222222222 + }, + { + "_id": "416adb8c-7d65-40e5-af88-8659c71194ce", + "name": "First Up Consultants | Picture Frame Bazaar - South Lysanneborough", + "sales": { + "revenue": 37157 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2024-09-02T02:39:50.269Z", + "covarianceSampForSales": 1901.1777777777777 + } +] +``` diff --git a/reference/operators/window-operators/$denserank.md b/reference/operators/window-operators/$denserank.md new file mode 100644 index 0000000..7fcd036 --- /dev/null +++ b/reference/operators/window-operators/$denserank.md @@ -0,0 +1,211 @@ +--- +title: $denseRank +description: The $denseRank operator assigns and returns a positional ranking for each document within a partition based on a specified sort order +type: operators +category: window-operators +--- + +# $denseRank + +The `$denseRank` operator sorts documents on one or more fields within a partition and assigns a ranking for each document relative to other documents in the result set. + +## Syntax + +```javascript +{ + $denseRank: {} +} +``` + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Retrieve a document rank for each store + +To calculate a document rank for each store under the First Up Consultants company, first run a query to filter on the company, then sort the resulting documents in descending order of sales and assign a document rank to each document in the sorted result set. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": ["First Up Consultants"] + } + } +}, { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "sales.totalSales": -1 + }, + "output": { + "denseRank": { + "$denseRank": {} + } + } + } +}, { + "$project": { + "company": 1, + "sales.totalSales": 1, + "denseRank": 1 + } +}]) +``` + +The first five results returned by this query are: + +```json +[ + { + "_id": "a0386810-b6f8-4b05-9d60-e536fb2b0026", + "sales": { + "revenue": 327583 + }, + "company": "First Up Consultants", + "denseRank": 1 + }, + { + "_id": "ad8af64a-d5bb-4162-9bb6-e5104126566d", + "sales": { + "revenue": 288582 + }, + "company": "First Up Consultants", + "denseRank": 2 + }, + { + "_id": "39acb3aa-f350-41cb-9279-9e34c004415a", + "sales": { + "revenue": 279183 + }, + "company": "First Up Consultants", + "denseRank": 3 + }, + { + "_id": "cd3d3782-17d1-451e-8b0f-4f10a68a8db7", + "sales": { + "revenue": 271604 + }, + "company": "First Up Consultants", + "denseRank": 4 + }, + { + "_id": "63ac4722-fc87-4526-a5e0-b5767d2807f7", + "sales": { + "revenue": 260409 + }, + "company": "First Up Consultants", + "denseRank": 5 + } +] +``` diff --git a/reference/operators/window-operators/$derivative.md b/reference/operators/window-operators/$derivative.md new file mode 100644 index 0000000..970ce74 --- /dev/null +++ b/reference/operators/window-operators/$derivative.md @@ -0,0 +1,211 @@ +--- +title: $derivative +description: The $derivative operator calculates the average rate of change of the value of a field within a specified window. +type: operators +category: window-operators +--- + +# $derivative + +The `$derivative` operator sorts documents on one or more fields within a partition and calculates the average rate of change of a field between the first and last documents within the window. + +## Syntax + +```javascript +{ + $derivative: { + input: < expression >, + unit: < timeWindow > + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | The expression or the field to calculate the rate of range| +| **`unit`** | The time window for the rate of change| + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Calculate the derivative for total sales + +To calculate the derivative of total sales for each store in the First Up Consultants company, first run a query to filter on the company, sort the resulting documents in ascending order of their last updated timestamps, and calculate the derivate (average rate of change) of total sales between the first and current document in the result set. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + }, + "$and": [{ + "lastUpdated": { + "$gt": ISODate("2024-12-01T03:06:24.180Z") + } + }, + { + "lastUpdated": { + "$lt": ISODate("2025-12-01T03:55:17.557Z") + } + } + ] + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "lastUpdated": 1 + }, + "output": { + "storeAverageSales": { + "$derivative": { + "input": "$sales.totalSales", + "unit": "week" + }, + "window": { + "range": [ + -1, + 0 + ], + "unit": "week" + } + } + } + } + }, + { + "$project": { + "lastUpdated": 1, + "storeAverageSales": 1 + } + } +]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "lastUpdated": "2025-06-11T10:48:01.291Z", + "storeAverageSales": 21554495.708753344 + } +] +``` diff --git a/reference/operators/window-operators/$documentnumber.md b/reference/operators/window-operators/$documentnumber.md new file mode 100644 index 0000000..fc0236b --- /dev/null +++ b/reference/operators/window-operators/$documentnumber.md @@ -0,0 +1,195 @@ +--- +title: $documentNumber +description: The $documentNumber operator assigns and returns a position for each document within a partition based on a specified sort order +type: operators +category: window-operators +--- + +# $documentNumber + +The `$documentNumber` operator sorts documents on one or more fields within a partition and assigns a document number for each document in the result set. + +## Syntax + +```javascript +{ + $documentNumber: {} +} +``` + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Retrieve a document number by total sales + +To retrieve a document number (positional ranking) for each store under the First Up Consultants company, first run a query to filter on the company name, then sort the results in ascending order of total sales, and assign a document number to each of the documents in the sorted result set. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": ["First Up Consultants"] + } + } +}, { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "sales.totalSales": -1 + }, + "output": { + "documentNumber": { + "$documentNumber": {} + } + } + } +}, { + "$project": { + "company": 1, + "documentNumber": 1 + } +}]) +``` + +The first 5 results returned by this query are: + +```json +[ + { + "_id": "39acb3aa-f350-41cb-9279-9e34c004415a", + "company": "First Up Consultants", + "documentNumber": 1 + }, + { + "_id": "26afb024-53c7-4e94-988c-5eede72277d5", + "company": "First Up Consultants", + "documentNumber": 2 + }, + { + "_id": "62438f5f-0c56-4a21-8c6c-6bfa479494ad", + "company": "First Up Consultants", + "documentNumber": 3 + }, + { + "_id": "bfb213fa-8db8-419f-8e5b-e7096120bad2", + "company": "First Up Consultants", + "documentNumber": 4 + }, + { + "_id": "14ab145b-0819-4d22-9e02-9ae0725fcda9", + "company": "First Up Consultants", + "documentNumber": 5 + } +] +``` diff --git a/reference/operators/window-operators/$expmovingavg.md b/reference/operators/window-operators/$expmovingavg.md new file mode 100644 index 0000000..596efed --- /dev/null +++ b/reference/operators/window-operators/$expmovingavg.md @@ -0,0 +1,285 @@ +--- +title: $expMovingAvg +description: The $expMovingAvg operator calculates the moving average of a field based on the specified number of documents to hold the highest weight +type: operators +category: window-operators +--- + +# $expMovingAvg + +The `$expMovingAvg` operator calculates the exponential moving average of the values of a specified field. + +## Syntax + +```javascript +{ + $expMovingAvg: { + input: < field to use for calculation >, + N: < number of recent documents with the highest weight + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | The field whose values are used to calculate the exponential moving average| +| **`N`** | The number of previous documents with the highest weight in calculating the exponential moving average| + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Calculate the exponential moving average of total sales + +To retrieve the exponential moving average of the total sales across all stores within the First Up Consultants company, first run a query to filter on the company. Then, sort the resulting documents in ascending order of their opening date. Finally, assigned the highest weight to the two most recent documents to calculate the exponential moving average of total sales. + +```javascript +db.stores.aggregate( +[{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + } + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "storeOpeningDate": 1 + }, + "output": { + "expMovingAvgForSales": { + "$expMovingAvg": { + "input": "$sales.totalSales", + "N": 2 + } + } + } + } + }, + { + "$project": { + "company": 1, + "name": 1, + "sales.totalSales": 1, + "storeOpeningDate": 1, + "expMovingAvgForSales": 1 + } + }]) +``` + +The firs two results returned by this query are: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "sales": { + "revenue": 37701 + }, + "company": "First Up Consultants", + "storeOpeningDate": { + "$date": 1633219200000 + }, + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "expMovingAvgForSales": 37701 + }, + { + "_id": "8e7a259b-f7d6-4ec5-a521-3bed53adc587", + "name": "First Up Consultants | Drone Stop - Lake Joana", + "sales": { + "revenue": 14329 + }, + "company": "First Up Consultants", + "storeOpeningDate": { + "$date": 1706958339311 + }, + "expMovingAvgForSales": 22119.666666666668 + } +] +``` + +### Example 2 - Calculate the exponential moving average of the total sales using the alpha parameter + +To retrieve the exponential moving average of the total sales across all stores within the First Up Consultants company, first run a query to filter on the company. Then, sort the resulting documents in ascending order of their opening date. Finally, specify a decay rate (alpha) to calculate the exponential moving average of total sales. A higher alpha value gives previous documents a lower weight in the calculation. + +```javascript +db.stores.aggregate( +[{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + } + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "storeOpeningDate": 1 + }, + "output": { + "expMovingAvgForSales": { + "$expMovingAvg": { + "input": "$sales.totalSales", + "alpha": 0.75 + } + } + } + } + }, + { + "$project": { + "company": 1, + "name": 1, + "sales.totalSales": 1, + "storeOpeningDate": 1, + "expMovingAvgForSales": 1 + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "sales": { + "revenue": 37701 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2021-10-03T00:00:00.000Z", + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "expMovingAvgForSales": 37701 + }, + { + "_id": "8e7a259b-f7d6-4ec5-a521-3bed53adc587", + "name": "First Up Consultants | Drone Stop - Lake Joana", + "sales": { + "revenue": 14329 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2024-09-02T00:05:39.311Z", + "expMovingAvgForSales": 20172 + } +] +``` diff --git a/reference/operators/window-operators/$integral.md b/reference/operators/window-operators/$integral.md new file mode 100644 index 0000000..ce22443 --- /dev/null +++ b/reference/operators/window-operators/$integral.md @@ -0,0 +1,218 @@ +--- +title: $integral +description: The $integral operator calculates the area under a curve with the specified range of documents forming the adjacent documents for the calculation. +type: operators +category: window-operators +--- + +# $integral + +The `$integral` operator calculates the area under a curve based on the specified range of documents sorted based on a specific field. + +## Syntax + +```javascript +{ + $integral: { + input: < expression > , + unit: < time window > + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | The field in the documents for the integral| +| **`unit`** | The specified time unit for the integral| + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1 - Calculate the integral of total sales + +To calculate the integral of total sales across all stores under the First Up Consultants company, first run a query to filter on the company name. Then, sort the resulting stores in ascending order of their opening dates. Lastly, calculate the integral of total sales from the first to the current document in the sorted result set. + +```javascript +db.stores.aggregate( +[{ + "$match": { + "company": { + "$in": [ + "First Up Consultants" + ] + } + } + }, + { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "storeOpeningDate": 1 + }, + "output": { + "salesIntegral": { + "$integral": { + "input": "$sales.revenue", + "unit": "hour" + }, + "window": { + "range": [ + "unbounded", + "current" + ], + "unit": "hour" + } + } + } + } + }, + { + "$project": { + "company": 1, + "name": 1, + "sales.revenue": 1, + "storeOpeningDate": 1, + "salesIntegral": 1 + } + }]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "sales": { + "revenue": 37701 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2021-10-03T00:00:00.000Z", + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "salesIntegral": 0 + }, + { + "_id": "8e7a259b-f7d6-4ec5-a521-3bed53adc587", + "name": "First Up Consultants | Drone Stop - Lake Joana", + "sales": { + "revenue": 14329 + }, + "company": "First Up Consultants", + "storeOpeningDate": "2024-09-02T00:05:39.311Z", + "salesIntegral": 664945851.9932402 + } +] +``` diff --git a/reference/operators/window-operators/$linearfill.md b/reference/operators/window-operators/$linearfill.md new file mode 100644 index 0000000..c10d1b2 --- /dev/null +++ b/reference/operators/window-operators/$linearfill.md @@ -0,0 +1,194 @@ +--- +title: $linearFill +description: The $linearFill operator interpolates missing values in a sequence of documents using linear interpolation. +type: operators +category: window-operators +--- + +# $linearFill + +The `$linearFill` operator interpolates missing values in a sequence of documents. The $linearFill operator performs linear interpolation for missing data, making it useful for datasets with gaps in values, such as time-series data. + +## Syntax + +```javascript +{ + $linearFill: { + input: < expression > , + sortBy: { + < field >: < 1 or - 1 > + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | The field or expression to interpolate missing values for. | +| **`sortBy`** | Specifies the field by which the data is sorted for interpolation, along with the sort order (1 for ascending, -1 for descending). | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Interpolating missing sales data + +To interpolate missing sales data, run a query to first partition the stores in the dataset by name. Then, use the $linearFill operator to interpolate the missing sales data across the stores within the partition. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": ["First Up Consultants"] + } + } + }, + { + "$setWindowFields": { + "partitionBy": "$name", + "sortBy": { + "storeOpeningDate": 1 + }, + "output": { + "interpolatedSales": { + "$linearFill": "$sales.totalSales" + } + } + } + } +]) +``` + +The first three results returned by this query are: + +```json +[ + { + "_id": "0f4c48fe-c43b-4083-a856-afe6dd902077", + "name": "First Up Consultants | Appliance Bargains - Feilmouth", + "interpolatedSales": 26630 + }, + { + "_id": "c4883253-7ccd-4054-a7e0-8aeb202307b5", + "name": "First Up Consultants | Appliance Bargains - New Kari", + "interpolatedSales": 31568 + }, + { + "_id": "a159ff5c-6ec5-4ca8-9672-e8903a54dd90", + "name": "First Up Consultants | Appliance Bargains - Schadenstad", + "interpolatedSales": 59926 + } +] +``` diff --git a/reference/operators/window-operators/$locf.md b/reference/operators/window-operators/$locf.md new file mode 100644 index 0000000..397f8cf --- /dev/null +++ b/reference/operators/window-operators/$locf.md @@ -0,0 +1,198 @@ +--- +title: $locf +description: The $locf operator propagates the last observed non-null value forward within a partition in a windowed query. +type: operators +category: window-operators +--- + +# $locf + +The `$locf` operator propagates the last observed non-null value forward within a partition in a windowed query. The $locf operator is particularly useful in filling missing data points in time-series data or other datasets with gaps. + +## Syntax + +```javascript +{ + $locf: { + input: , + sortBy: + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | The expression that resolves to the field whose value you want to propagate. | +| **`sortBy`** | A document that specifies the sort order for the partition. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Using `$locf` to fill missing time series data + +To propagate the most recent non-null value for the lastUpdated field across stores within the "First Up Consultants" company, first run a query to partition the stores within the company. Then, use the $lecf operator to propagate the last non-null value for the field for all stores within the partition. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": ["First Up Consultants"] + } + } +}, { + "$setWindowFields": { + "partitionBy": "$name", + "sortBy": { + "sales.revenue": 1 + }, + "output": { + "lastUpdatedDate": { + "$locf": { + "lastUpdated": 1 + } + } + } + } +}, { + "$project": { + "company": 1, + "name": 1, + "lastObservedDiscount": 1 + } +}]) +``` + +The first three results returned by this query are: + +```json +[ + { + "_id": "0f4c48fe-c43b-4083-a856-afe6dd902077", + "name": "First Up Consultants | Appliance Bargains - Feilmouth", + "company": "First Up Consultants" + }, + { + "_id": "c4883253-7ccd-4054-a7e0-8aeb202307b5", + "name": "First Up Consultants | Appliance Bargains - New Kari", + "company": "First Up Consultants" + }, + { + "_id": "a159ff5c-6ec5-4ca8-9672-e8903a54dd90", + "name": "First Up Consultants | Appliance Bargains - Schadenstad", + "company": "First Up Consultants" + } +] +``` diff --git a/reference/operators/window-operators/$rank.md b/reference/operators/window-operators/$rank.md new file mode 100644 index 0000000..11db7c1 --- /dev/null +++ b/reference/operators/window-operators/$rank.md @@ -0,0 +1,207 @@ +--- +title: $rank +description: The $rank operator ranks documents within a partition based on a specified sort order. +type: operators +category: window-operators +--- + +# $rank + +The `$rank` operator assigns a rank to each document within a partition of a dataset. The rank is determined based on a specified sort order. + +## Syntax + +```javascript +{ + $setWindowFields: { + partitionBy: < expression > , + sortBy: { + < field >: < order > + }, + output: { + < outputField >: { + $rank: {} + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`partitionBy`** | Specifies the expression to group documents into partitions. If omitted, all documents are treated as a single partition. | +| **`sortBy`** | Defines the sort order for ranking. Must be specified for `$rank`. | +| **`output`** | Contains the field where the rank value is stored. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "0fcc0bf0-ed18-4ab8-b558-9848e18058f4", + "name": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "location": { + "lat": -89.2384, + "lon": -46.4012 + }, + "staff": { + "totalStaff": { + "fullTime": 8, + "partTime": 20 + } + }, + "sales": { + "totalSales": 75670, + "salesByCategory": [ + { + "categoryName": "Wine Accessories", + "totalSales": 34440 + }, + { + "categoryName": "Bitters", + "totalSales": 39496 + }, + { + "categoryName": "Rum", + "totalSales": 1734 + } + ] + }, + "promotionEvents": [ + { + "eventName": "Unbeatable Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 7, + "Day": 2 + } + }, + "discounts": [ + { + "categoryName": "Whiskey", + "discountPercentage": 7 + }, + { + "categoryName": "Bitters", + "discountPercentage": 15 + }, + { + "categoryName": "Brandy", + "discountPercentage": 8 + }, + { + "categoryName": "Sports Drinks", + "discountPercentage": 22 + }, + { + "categoryName": "Vodka", + "discountPercentage": 19 + } + ] + }, + { + "eventName": "Steal of a Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 29 + } + }, + "discounts": [ + { + "categoryName": "Organic Wine", + "discountPercentage": 19 + }, + { + "categoryName": "White Wine", + "discountPercentage": 20 + }, + { + "categoryName": "Sparkling Wine", + "discountPercentage": 19 + }, + { + "categoryName": "Whiskey", + "discountPercentage": 17 + }, + { + "categoryName": "Vodka", + "discountPercentage": 23 + } + ] + } + ] +} +``` + +### Example 1: Ranking stores by sales volume + +To rank all stores within the "First Up Consultants" company by sales volume, first run a query to partition the stores within the company. Then, sort the resulting stores in ascending order of sales volume and use the $rank operator to rank the sorted documents in the result set. + +```javascript +db.stores.aggregate([{ + "$match": { + "company": { + "$in": ["First Up Consultants"] + } + } +}, { + "$setWindowFields": { + "partitionBy": "$company", + "sortBy": { + "sales.totalSales": -1 + }, + "output": { + "rankBySales": { + "$rank": {} + } + } + } +}, { + "$project": { + "company": 1, + "name": 1, + "rankBySales": 1 + } +}]) +``` + +The first three results returned by this query are: + +```json +[ + { + "_id": "a0386810-b6f8-4b05-9d60-e536fb2b0026", + "name": "First Up Consultants | Electronics Stop - South Thelma", + "company": "First Up Consultants", + "rankBySales": 1 + }, + { + "_id": "ad8af64a-d5bb-4162-9bb6-e5104126566d", + "name": "First Up Consultants | Electronics Emporium - South Carmenview", + "company": "First Up Consultants", + "rankBySales": 2 + }, + { + "_id": "39acb3aa-f350-41cb-9279-9e34c004415a", + "name": "First Up Consultants | Bed and Bath Pantry - Port Antone", + "company": "First Up Consultants", + "rankBySales": 3 + } +] +``` diff --git a/reference/operators/window-operators/$shift.md b/reference/operators/window-operators/$shift.md new file mode 100644 index 0000000..a5e5328 --- /dev/null +++ b/reference/operators/window-operators/$shift.md @@ -0,0 +1,80 @@ +--- +title: $shift usage on DocumentDB +description: A window operator that shifts values within a partition and returns the shifted value. +type: operators +category: window-operators +--- + +# $shift + +The `$shift` operator is a window operator used in aggregation pipelines to shift values within a partition and return the shifted value. It is useful for operations where you need to compare values from adjacent documents in a sorted partition. + +## Syntax + +```javascript +{ + $shift: { + output: , + by: , + default: + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`output`** | Specifies the field or expression whose value will be shifted. | +| **`by`** | Specifies the number of positions to shift the value. Positive values shift forward, while negative values shift backward. | +| **`default`** | Specifies the default value to return if the shift operation goes out of bounds. | + +## Example(s) + +### Example 1: Shifting sales data + +This example demonstrates how to use `$shift` to calculate the previous sales value for each document in a sorted partition of sales data. + +```javascript +db.collection.aggregate([ + { + $setWindowFields: { + partitionBy: "$sales.salesByCategory.categoryName", + sortBy: { "sales.salesByCategory.totalSales": 1 }, + output: { + previousSales: { + $shift: { + output: "$sales.salesByCategory.totalSales", + by: -1, + default: null + } + } + } + } + } +]) +``` + +### Example 2: Shifting promotional event dates + +This example calculates the previous promotional event’s start date by sorting all events by startDate. Since we want to treat all events together, we don’t partition. + +```javascript +db.promotionEvents.aggregate([ + { + $setWindowFields: { + partitionBy: null, + sortBy: { "promotionalDates.startDate": 1 }, + output: { + previousStartDate: { + $shift: { + output: "$promotionalDates.startDate", + by: -1, + default: null + } + } + } + } + } +]) +```