From b921d25ad5b09b519fe9579a11f0e43d7930e1cc Mon Sep 17 00:00:00 2001 From: seesharprun Date: Tue, 9 Dec 2025 11:32:43 -0500 Subject: [PATCH] Add reference files --- reference/operators/accumulators/$avg.md | 390 ++++++++++++++ reference/operators/accumulators/$bottom.md | 246 +++++++++ reference/operators/accumulators/$bottomn.md | 276 ++++++++++ reference/operators/accumulators/$count.md | 391 ++++++++++++++ reference/operators/accumulators/$first.md | 294 +++++++++++ reference/operators/accumulators/$firstn.md | 326 ++++++++++++ reference/operators/accumulators/$last.md | 208 ++++++++ reference/operators/accumulators/$lastn.md | 413 +++++++++++++++ reference/operators/accumulators/$max.md | 432 ++++++++++++++++ reference/operators/accumulators/$maxn.md | 255 +++++++++ reference/operators/accumulators/$median.md | 193 +++++++ reference/operators/accumulators/$min.md | 485 ++++++++++++++++++ reference/operators/accumulators/$minn.md | 308 +++++++++++ .../operators/accumulators/$percentile.md | 212 ++++++++ .../operators/accumulators/$stddevpop.md | 284 ++++++++++ .../operators/accumulators/$stddevsamp.md | 172 +++++++ reference/operators/accumulators/$sum.md | 316 ++++++++++++ reference/operators/accumulators/$top.md | 288 +++++++++++ reference/operators/accumulators/$topn.md | 327 ++++++++++++ 19 files changed, 5816 insertions(+) create mode 100644 reference/operators/accumulators/$avg.md create mode 100644 reference/operators/accumulators/$bottom.md create mode 100644 reference/operators/accumulators/$bottomn.md create mode 100644 reference/operators/accumulators/$count.md create mode 100644 reference/operators/accumulators/$first.md create mode 100644 reference/operators/accumulators/$firstn.md create mode 100644 reference/operators/accumulators/$last.md create mode 100644 reference/operators/accumulators/$lastn.md create mode 100644 reference/operators/accumulators/$max.md create mode 100644 reference/operators/accumulators/$maxn.md create mode 100644 reference/operators/accumulators/$median.md create mode 100644 reference/operators/accumulators/$min.md create mode 100644 reference/operators/accumulators/$minn.md create mode 100644 reference/operators/accumulators/$percentile.md create mode 100644 reference/operators/accumulators/$stddevpop.md create mode 100644 reference/operators/accumulators/$stddevsamp.md create mode 100644 reference/operators/accumulators/$sum.md create mode 100644 reference/operators/accumulators/$top.md create mode 100644 reference/operators/accumulators/$topn.md diff --git a/reference/operators/accumulators/$avg.md b/reference/operators/accumulators/$avg.md new file mode 100644 index 0000000..809632a --- /dev/null +++ b/reference/operators/accumulators/$avg.md @@ -0,0 +1,390 @@ +--- +title: $avg +description: Computes the average of numeric values for documents in a group, bucket, or window. +type: operators +category: accumulators +--- + +# $avg + +The `$avg` operator computes the average of numeric values across groups of documents or within defined windows. + +## Syntax + +```javascript +$avg: +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **``** | Specifies the field or expression to calculate the average. Non-numeric values are ignored. | + +## 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 average sales by category + +To calculate the average sales across all stores within each category, first run a query to group documents within each sales category. Then, calculate the average sales across all documents within each group. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $group: { + _id: "$sales.salesByCategory.categoryName", + avgSales: { + $avg: "$sales.salesByCategory.totalSales" + } + } + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "Christmas Trees", + "avgSales": 25987.956989247312 + }, + { + "_id": "Nuts", + "avgSales": 25115.98795180723 + }, + { + "_id": "Camping Tables", + "avgSales": 25012.546153846153 + }, + { + "_id": "Music Theory Books", + "avgSales": 26138.80769230769 + }, + { + "_id": "Fortified Wine", + "avgSales": 24748.672727272726 + }, + { + "_id": "Children's Mystery", + "avgSales": 23764.044444444444 + }, + { + "_id": "Short Throw Projectors", + "avgSales": 27157.472222222223 + }, + { + "_id": "Pliers", + "avgSales": 26712.875 + }, + { + "_id": "Bluetooth Headphones", + "avgSales": 26311.58653846154 + }, + { + "_id": "Video Storage", + "avgSales": 26121.475 + }, + { + "_id": "Cleansers", + "avgSales": 25836.397058823528 + }, + { + "_id": "Camera Straps", + "avgSales": 22487.609375 + }, + { + "_id": "Carry-On Bags", + "avgSales": 24294.263157894737 + }, + { + "_id": "Disinfectant Wipes", + "avgSales": 27066.929411764704 + }, + { + "_id": "Insignia Smart TVs", + "avgSales": 27096.83950617284 + }, + { + "_id": "Toner Refill Kits", + "avgSales": 24963.71052631579 + }, + { + "_id": "iPads", + "avgSales": 22583.882352941175 + }, + { + "_id": "Memory Foam Mattresses", + "avgSales": 28073.05172413793 + }, + { + "_id": "Storage Baskets", + "avgSales": 24092.514705882353 + }, + { + "_id": "Body Spray", + "avgSales": 26080.84375 + } +] +``` + +### Example 2: Using `$avg` in `$bucket` + +To get the averages sales within specific sales boundaries, this query creates buckets based on sales values and calculates the avg sales within each bucket. + +```javascript +db.stores.aggregate([{ + $bucket: { + groupBy: "$sales.totalSales", + boundaries: [0, 1000, 5000, 10000], + default: "Other", + output: { + avgSales: { + $avg: "$sales.totalSales" + } + } + } +}]) +``` + +This query returns the following results: + +```json +[ + { + "_id": 1000, + "avgSales": 3029.053674121406 + }, + { + "_id": "Other", + "avgSales": 52169.85442987472 + }, + { + "_id": 0, + "avgSales": 576.3164179104477 + }, + { + "_id": 5000, + "avgSales": 7538.786819770345 + } +] +``` + +### Example 3: Using `$avg` in `$setWindowFields` + +To get the average discount per store in 2023 for "Laptops", first run a query to partition stores by company and filter discount promotions for "Laptops". Then calculate the average discount percentage within each partitioned result set. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + + // Filter only Laptops category and events in 2023 + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023, + "promotionEvents.discounts.categoryName": "Laptops" + } + }, + + // Use $setWindowFields to calculate average discount by city + { + $setWindowFields: { + partitionBy: "$company", + output: { + avgDiscount: { + $avg: "$promotionEvents.discounts.discountPercentage", + window: { + documents: ["unbounded", "unbounded"] + } + } + } + } + }, + + // Group by city to return one result per city + { + $group: { + _id: "$company", + avgDiscount: { + $first: "$avgDiscount" + } + } + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "VanArsdel, Ltd.", + "avgDiscount": 14.461538461538462 + }, + { + "_id": "Proseware, Inc.", + "avgDiscount": 16.25 + }, + { + "_id": "Fabrikam, Inc.", + "avgDiscount": 14.454545454545455 + }, + { + "_id": "Contoso, Ltd.", + "avgDiscount": 14.384615384615385 + }, + { + "_id": "Fourth Coffee", + "avgDiscount": 13.625 + }, + { + "_id": "Trey Research", + "avgDiscount": 17.785714285714285 + }, + { + "_id": "Adatum Corporation", + "avgDiscount": 11.666666666666666 + }, + { + "_id": "Relecloud", + "avgDiscount": 14.375 + }, + { + "_id": "Lakeshore Retail", + "avgDiscount": 15.846153846153847 + }, + { + "_id": "Northwind Traders", + "avgDiscount": 14.2 + }, + { + "_id": "First Up Consultants", + "avgDiscount": 11.25 + }, + { + "_id": "Wide World Importers", + "avgDiscount": 15.571428571428571 + }, + { + "_id": "Tailwind Traders", + "avgDiscount": 16.166666666666668 + } +] +``` diff --git a/reference/operators/accumulators/$bottom.md b/reference/operators/accumulators/$bottom.md new file mode 100644 index 0000000..e285dba --- /dev/null +++ b/reference/operators/accumulators/$bottom.md @@ -0,0 +1,246 @@ +--- +title: $bottom +description: The $bottom operator returns the last document from the query's result set sorted by one or more fields +type: operators +category: accumulators +--- + +# $bottom + +The `$bottom` operator sorts documents on one or more fields specified by the query and returns the last document matching the filtering criteria. + +## Syntax + +```javascript +{ + $bottom: { + output: [listOfFields], + sortBy: { + : < sortOrder > + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`listOfFields`** | The list of fields to be returned from the last document in the result set| +| **`fieldName`** | The field to use for sorting the result set| +| **`sortOrder`** | 1 or -1. 1 implies sorting in ascending order of the value of the field while -1 implies sorting in descending order of the values of the field| + +## 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: Find the store with lowest total sales + +Suppose we want to determine the store within the First Up Consultants company with the lowest total sales, run a query to retrieve documents within the First Up Consultants company, sort the documents in descending order of total sales and return the last document in the sorted result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $group: { + _id: "$company", + bottomSales: { + $bottom: { + output: ["$company", "$sales"], + sortBy: { + "sales.revenue": -1 + } + } + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "bottomSales": [ + "First Up Consultants", + { + "totalSales": 119, + "salesByCategory": [ + { + "categoryName": "Skirts", + "totalSales": 109 + } + ] + } + ] +}] +``` + +### Example 2: Find the category per store with the lowest sales + +To find the category with the lowest sales per store, run a query to retrieve stores with multiple sales categories, sort the categories in descending order of total sales within each store and return the last document in the sorted result set. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $match: { + "sales.salesByCategory.totalSales": { + $exists: true + } + } + }, + { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + lowestCategory: { + $bottom: { + sortBy: { + "sales.salesByCategory.totalSales": 1 + }, + output: { + categoryName: "$sales.salesByCategory.categoryName", + totalSales: "$sales.salesByCategory.totalSales" + } + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "b1d86d1f-8705-4157-b64c-a9eda0df4921", + "storeName": "VanArsdel, Ltd. | Baby Products Haven - West Kingfort", + "lowestCategory": { "categoryName": "Baby Monitors", "totalSales": 49585 } + }, + { + "_id": "22e6367e-8341-415f-9795-118d2b522abf", + "storeName": "Adatum Corporation | Outdoor Furniture Mart - Port Simone", + "lowestCategory": { "categoryName": "Outdoor Benches", "totalSales": 4976 } + } +] +``` diff --git a/reference/operators/accumulators/$bottomn.md b/reference/operators/accumulators/$bottomn.md new file mode 100644 index 0000000..392402e --- /dev/null +++ b/reference/operators/accumulators/$bottomn.md @@ -0,0 +1,276 @@ +--- +title: $bottomN +description: The $bottomN operator returns the last N documents from the result sorted by one or more fields +type: operators +category: accumulators +--- + +# $bottomN + +The $bottomN operator sorts documents on one or more fields specified by the query and returns the last N documents matching the filtering criteria. + +## Syntax + +```javascript +{ + $bottomN: { + output: [listOfFields], + sortBy: { + : < sortOrder > + }, + n: < numDocumentsToReturn > + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`listOfFields`** | The list of fields to be returned for the last document in the result set| +| **`fieldName`** | The field to use for sorting the result set| +| **`sortOrder`** | 1 or -1. 1 implies sorting in ascending order of the value of the field while -1 implies sorting in descending order of the values of the field| +| **`n`** | The number of documents to return from the bottom of the sorted result set | + +## 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: Find the bottom two stores by total sales + +To determine the two stores in the First Up Consultants company with the lowest sales, run a query to retrieve stores within the "First Up Consultants" company, sort the resulting documents in descending order of total sales and return the last two documents from the sorted result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $group: { + _id: "$company", + bottomSales: { + $bottomN: { + output: ["$company", "$sales"], + sortBy: { + "sales.revenue": -1 + }, + n: 2 + } + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "bottomSales": [ + [ + "First Up Consultants", + { + "salesByCategory": [ + { + "categoryName": "Skirts", + "totalSales": 109 + } + ], + "revenue": 109 + } + ], + [ + "First Up Consultants", + { + "salesByCategory": [ + { + "categoryName": "Mirrors", + "totalSales": 120 + } + ], + "revenue": 120 + } + ] + ] +} +] +``` + +### Example 2: Find the bottom two categories by total sales within each store + +To determine the two lowest performing categories by total sales within each store, run a query to retrieve documents with at least two sales categories, sort the categories in descending order of total sales and finally return the bottom two categories per store. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" +}, { + $match: { + "sales.salesByCategory.totalSales": { + $exists: true + } + } +}, { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + categoryCount: { + $sum: 1 + }, + bottomTwoCategories: { + $bottomN: { + n: 2, + sortBy: { + "sales.salesByCategory.totalSales": -1 + }, + output: { + categoryName: "$sales.salesByCategory.categoryName", + totalSales: "$sales.sale" + } + } + } + } +}, { + $match: { + categoryCount: { + $gte: 2 + } + } +}]) +``` + +The first result returned by this query is: + +```json +[ + { + "_id": "64ec6589-068a-44a6-be5b-9d37bb0a90f1", + "storeName": "First Up Consultants | Computer Gallery - West Cathrine", + "categoryCount": 8, + "bottomTwoCategories": [ + { + "categoryName": "Gaming Controllers", + "totalSales": null + }, + { + "categoryName": "Network Adapters", + "totalSales": null + } + ] + } +] +``` diff --git a/reference/operators/accumulators/$count.md b/reference/operators/accumulators/$count.md new file mode 100644 index 0000000..bba00e7 --- /dev/null +++ b/reference/operators/accumulators/$count.md @@ -0,0 +1,391 @@ +--- +title: $count +description: The `$count` operator is used to count the number of documents that match a query filtering criteria. +type: operators +category: accumulators +--- + +# $count + +The `$count` operator is used to count the number of documents that match a specified query filter. The count operator is useful for summarizing data or generating counts for specific groupings. + +## Syntax + +```javascript +{ + $count: "" +} +``` + +## Parameters + +| Parameter | Description | +|----------------|-----------------------------------------------------------------------------| +| **``** | The name of the field in the output document where the count will be 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: Retrieve the count of all documents + +To retrieve the count of documents within the collection, simply run a count query without query filters. + +```javascript +db.stores.aggregate([{ + $count: "totalDocuments" +}]) +``` + +This query returns the following result: + +```json +[ + { + "totalDocuments": 41501 + } +] +``` + +### Example 2: Count documents grouped by a specific field + +To retrieve the count of documents within each sales category, first run a query to group documents by sales category. Then run a count query within each category. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $group: { + _id: "$sales.salesByCategory.categoryName", + totalCount: { + $count: {} + } + } + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "Christmas Trees", + "totalCount": 93 + }, + { + "_id": "Nuts", + "totalCount": 83 + }, + { + "_id": "Camping Tables", + "totalCount": 130 + }, + { + "_id": "Music Theory Books", + "totalCount": 52 + }, + { + "_id": "Fortified Wine", + "totalCount": 55 + }, + { + "_id": "Children's Mystery", + "totalCount": 45 + }, + { + "_id": "Short Throw Projectors", + "totalCount": 72 + }, + { + "_id": "Pliers", + "totalCount": 56 + }, + { + "_id": "Bluetooth Headphones", + "totalCount": 104 + }, + { + "_id": "Video Storage", + "totalCount": 80 + }, + { + "_id": "Cleansers", + "totalCount": 68 + }, + { + "_id": "Camera Straps", + "totalCount": 64 + }, + { + "_id": "Carry-On Bags", + "totalCount": 57 + }, + { + "_id": "Disinfectant Wipes", + "totalCount": 85 + }, + { + "_id": "Insignia Smart TVs", + "totalCount": 81 + }, + { + "_id": "Toner Refill Kits", + "totalCount": 38 + }, + { + "_id": "iPads", + "totalCount": 51 + }, + { + "_id": "Memory Foam Mattresses", + "totalCount": 58 + }, + { + "_id": "Storage Baskets", + "totalCount": 68 + }, + { + "_id": "Body Spray", + "totalCount": 96 + } +] +``` + +### Example 3: Count the number of promotion events + +To count the number of promotion events across all stores, first run a query to first unwind by promotion events and then count the distinct promotion events. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $count: "totalPromotionEvents" + } +]) +``` + +This query returns the following result: + +```json +[ + { + "totalPromotionEvents": 145673 + } +] +``` + +### Example 4: Using `$count` in `$setWindowFields` + +To get sales for Laptops promotions per store, first run a query to filter promotion events for laptops in 2023. Then partition the resulting stores by company. Lastly, run a count query across the partitioned stores to return the results. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + // Filter only for Laptop discounts in 2023 + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023, + "promotionEvents.discounts.categoryName": "Laptops" + } + }, + // Add sales count by city using window function + { + $setWindowFields: { + partitionBy: "$company", + output: { + salesCount: { + $count: {}, + window: { + documents: ["unbounded", "unbounded"] + } + } + } + } + }, + // Group to return a single result per city + { + $group: { + _id: "$company", + salesCount: { + $first: "$salesCount" + } + } + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "VanArsdel, Ltd.", + "salesCount": 13 + }, + { + "_id": "Proseware, Inc.", + "salesCount": 12 + }, + { + "_id": "Fabrikam, Inc.", + "salesCount": 11 + }, + { + "_id": "Contoso, Ltd.", + "salesCount": 13 + }, + { + "_id": "Fourth Coffee", + "salesCount": 8 + }, + { + "_id": "Trey Research", + "salesCount": 14 + }, + { + "_id": "Adatum Corporation", + "salesCount": 12 + }, + { + "_id": "Relecloud", + "salesCount": 16 + }, + { + "_id": "Lakeshore Retail", + "salesCount": 13 + }, + { + "_id": "Northwind Traders", + "salesCount": 5 + }, + { + "_id": "First Up Consultants", + "salesCount": 4 + }, + { + "_id": "Wide World Importers", + "salesCount": 7 + }, + { + "_id": "Tailwind Traders", + "salesCount": 12 + } +] +``` diff --git a/reference/operators/accumulators/$first.md b/reference/operators/accumulators/$first.md new file mode 100644 index 0000000..6123485 --- /dev/null +++ b/reference/operators/accumulators/$first.md @@ -0,0 +1,294 @@ +--- +title: $first +description: The $first operator returns the first value in a group according to the group's sorting order. +type: operators +category: accumulators +--- + +# $first + +The $first operator sorts documents on one or more fields specified by the query and returns the first document matching the filtering criteria. If no sorting order is specified, the order is undefined. + +## Syntax + +```javascript +{ + $first: +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`expression`** | The expression to evaluate and return the first document from the result set| + +## 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: Get the least recently updated document + +To retrieve the least recently updated store under the First Up Consultants company, run a query to fetch all documents belonging to the "First Up Consultants" company, sort the resulting documents in ascending order of the lastUpdated field and return the first document in the result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $sort: { + lastUpdated: 1 + } +}, { + $group: { + _id: "$company", + firstUpdated: { + $first: "$lastUpdated" + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "firstUpdated": "ISODate('2025-06-11T10:48:01.291Z')" + } +] +``` + +### Example 2: Get first category by sales amount per store + +To retrieve the first category (alphabetically) within each store, run a query to sort the list of sales categories within each store and return the first category from the sorted result set per store. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $sort: { + "_id": 1, + "sales.salesByCategory.categoryName": 1 + } + }, + { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + totalSales: { + $first: "$sales.totalSales" + }, + firstCategory: { + $first: { + categoryName: "$sales.salesByCategory.categoryName", + categoryTotalSales: "$sales.salesByCategory.totalSales" + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "64ec6589-068a-44a6-be5b-9d37bb0a90f1", + "storeName": "First Up Consultants | Computer Gallery - West Cathrine", + "totalSales": 186829, + "firstCategory": { + "categoryName": "Cases", + "categoryTotalSales": 36386 + } + }, + { + "_id": "14343900-2a5c-44bf-a52b-9efe63579866", + "storeName": "Northwind Traders | Home Improvement Closet - West Evanside", + "totalSales": 35371, + "firstCategory": { + "categoryName": "Doors", + "categoryTotalSales": 21108 + } + } +] +``` + +### Example 3: Get first promotion event per store + +To retrieve the first promotion event for each store, run a query to sort the list of promotion events within each store by startDate and return the first event from the sorted result set per store. + +Get the first promotion event for each store based on start date. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $sort: { + "_id": 1, + "promotionEvents.promotionalDates.startDate.Year": 1, + "promotionEvents.promotionalDates.startDate.Month": 1, + "promotionEvents.promotionalDates.startDate.Day": 1 + } + }, + { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + firstPromotionEvent: { + $first: { + eventName: "$promotionEvents.eventName", + startYear: "$promotionEvents.promotionalDates.startDate.Year", + startMonth: "$promotionEvents.promotionalDates.startDate.Month" + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "64ec6589-068a-44a6-be5b-9d37bb0a90f1", + "storeName": "First Up Consultants | Computer Gallery - West Cathrine", + "firstPromotionEvent": { + "eventName": "Crazy Markdown Madness", + "startYear": 2024, + "startMonth": 6 + } + }, + { + "_id": "a58d0356-493b-44e6-afab-260aa3296930", + "storeName": "Fabrikam, Inc. | Outdoor Furniture Nook - West Lexie", + "firstPromotionEvent": { + "eventName": "Price Drop Palooza", + "startYear": 2023, + "startMonth": 9 + } + } +] +``` diff --git a/reference/operators/accumulators/$firstn.md b/reference/operators/accumulators/$firstn.md new file mode 100644 index 0000000..0898947 --- /dev/null +++ b/reference/operators/accumulators/$firstn.md @@ -0,0 +1,326 @@ +--- +title: $firstN +description: The $firstN operator sorts documents on one or more fields specified by the query and returns the first N document matching the filtering criteria +type: operators +category: accumulators +--- + +# $firstN + +The `$firstN` operator returns the first N values in a group according to the group's sorting order. If no sorting order is specified, the order is undefined. + +## Syntax + +```javascript +{ + $firstN: { + input: [listOfFields], + sortBy: { + : + }, + n: + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`listOfFields`** | The list of fields to be returned for the first N documents in the result set| +| **`fieldName`** | The field to use for sorting the result set| +| **`sortOrder`** | 1 or -1. 1 implies sorting in ascending order of the value of the field while -1 implies sorting in descending order of the values of the field| +| **`n`** | The number of documents to return from the top of the sorted result set | + +## 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: Use $firstN operator as accumulator to find first two stores by total sales + +To get the top two stores by total sales, run a query to sort all documents in descending order of sales.totalSales and return the first two documents from the sorted result set. + +```javascript +db.stores.aggregate([{ + $sort: { + "sales.totalSales": -1 + } + }, + { + $group: { + _id: null, + topTwoStores: { + $firstN: { + n: 2, + input: { + storeId: "$_id", + storeName: "$name", + totalSales: "$sales.totalSales" + } + } + } + } + } +]) +``` + +This query returns the following result: + +```json +[ + { + "_id": null, + "topTwoStores": [ + { + "storeId": "ffe155dd-caa2-4ac1-8ec9-0342241a84a3", + "storeName": "Lakeshore Retail | Electronics Stop - Vicentastad", + "totalSales": 399426 + }, + { + "storeId": "cba62761-10f8-4379-9eea-a9006c667927", + "storeName": "Fabrikam, Inc. | Electronics Nook - East Verlashire", + "totalSales": 374845 + } + ] + } +] +``` + +### Example 2: Use $firstN operator as accumulator to find first two categories per store + +To retrieve the first two categories by total sales within each store, run a query to sort all documents in descending order of sales.totalSales within the scope of each store and return the first two categories from the sorted result set per store. + +```javascript +db.stores.aggregate([ + { $unwind: "$sales.salesByCategory" }, + { + $match: { + "sales.salesByCategory.totalSales": { $exists: true } + } + }, + { + $sort: { + "_id": 1, + "sales.salesByCategory.totalSales": -1 + } + }, + { + $group: { + _id: "$_id", + storeName: { $first: "$name" }, + categoryCount: { $sum: 1 }, + firstTwoCategories: { + $push: { + categoryName: "$sales.salesByCategory.categoryName", + totalSales: "$sales.salesByCategory.totalSales" + } + } + } + }, + { + $project: { + storeName: 1, + categoryCount: 1, + firstTwoCategories: { $slice: ["$firstTwoCategories", 2] } + } + }, + { + $match: { + categoryCount: { $gte: 2 } + } + }, + { $limit: 2 } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "2e07b49d-1730-491b-b847-44b6a34812c1", + "storeName": "VanArsdel, Ltd. | Electronics Market – North Bransonborough", + "categoryCount": 3, + "firstTwoCategories": [ + { + "categoryName": "iPads", + "totalSales": 37113 + }, + { + "categoryName": "Laptops", + "totalSales": 9175 + } + ] + }, + { + "_id": "1bec7539-dc75-4f7e-b4e8-afdf8ff2f234", + "storeName": "Adatum Corporation | Health Food Market – East Karina", + "categoryCount": 2, + "firstTwoCategories": [ + { + "categoryName": "Protein Bars", + "totalSales": 49900 + }, + { + "categoryName": "Superfoods", + "totalSales": 39683 + } + ] + } +] +``` + +### Example 3: Use `firstN` operator as array-expression to find first three sales categories + +The example demonstrates the operator usage to find the first three sales categories for analysis. + +```javascript +db.stores.aggregate([ + { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} }, + { + $project: { + name: 1, + totalSales: "$sales.totalSales", + firstThreeCategories: { + $firstN: { + input: "$sales.salesByCategory", + n: 3 + } + } + } + } +]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74", + "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", + "totalSales": 165000, + "firstThreeCategories": [ + { + "categoryName": "Sound Bars", + "totalSales": 2120 + }, + null, + { + "categoryName": "Game Controllers", + "totalSales": 43522 + } + ] + } +] +``` diff --git a/reference/operators/accumulators/$last.md b/reference/operators/accumulators/$last.md new file mode 100644 index 0000000..86cb9fb --- /dev/null +++ b/reference/operators/accumulators/$last.md @@ -0,0 +1,208 @@ +--- +title: $last +description: The $last operator returns the last document from the result sorted by one or more fields +type: operators +category: accumulators +--- + +# $last + +The `$last` operator sorts documents on one or more fields specified by the query and returns the last document matching the filtering criteria. + +## Syntax + +```javascript +{ + "$last": +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`expression`** | The expression to evaluate and return the last document from the result set| + +## 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: Get the last updated store within a company + +To retrieve the more recently updated store within the First Up Consultants company, run a query to fetch all stores within First Up Consultants, sort the documents in ascending order of the lastUpdated field and return the last document from the sorted results. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $sort: { + lastUpdated: 1 + } +}, { + $group: { + _id: "$company", + lastUpdated: { + $last: "$lastUpdated" + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "lastUpdated": "ISODate('2024-12-31T13:01:19.097Z')" + } +] +``` + +### Example 2 - Using the window operator + +To retrieve the more recently updated store within each company, run a query to partition the results by the company field and sort the documents within each partition in ascending order of lastUpdated field and return the sorted results per partition. + +```javascript +db.stores.aggregate([{ + $setWindowFields: { + partitionBy: "$company", + sortBy: { + lastUpdated: 1 + }, + output: { + lastUpdatedDateForStore: { + $last: "$lastUpdated", + window: { + documents: ["current", "unbounded"] + } + } + } + } +}]) +``` + +The first result returned by this query is: + +```json +[ + { + "_id": "First Up Consultants", + "lastUpdated": "ISODate('2024-12-31T13:01:19.097Z')" + } +] +``` diff --git a/reference/operators/accumulators/$lastn.md b/reference/operators/accumulators/$lastn.md new file mode 100644 index 0000000..c62ea9b --- /dev/null +++ b/reference/operators/accumulators/$lastn.md @@ -0,0 +1,413 @@ +--- +title: $lastN +description: The $lastN accumulator operator returns the last N values in a group of documents. +type: operators +category: accumulators +--- + +# $lastN + +The `$lastN` accumulator operator returns the last N values in a group of documents for a specified expression. It's useful when you need to retrieve multiple final values from a sorted collection rather than just the single last value. + +## Syntax + +```javascript +{ + $group: { + _id: < expression > , + < field >: { + $lastN: { + n: < number >, + input: < expression > + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`n`** | The number of values to return. Must be a positive integer. | +| **`input`** | The expression that specifies the field or value to return the last N occurrences of. | + +## 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: Use $lastN as accumulator to find last two promotion events by store + +To retrieve the last two promotion events for each store, run a query to sort promotion events in ascending order of their start dates, group the sorted events by store and return the last two events within each store. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $sort: { + "promotionEvents.promotionalDates.startDate.Year": 1, + "promotionEvents.promotionalDates.startDate.Month": 1, + "promotionEvents.promotionalDates.startDate.Day": 1 + } + }, + { + $group: { + _id: "$_id", + storeName: { + $last: "$name" + }, + lastTwoPromotions: { + $lastN: { + input: "$promotionEvents.eventName", + n: 2 + } + }, + lastTwoPromotionDates: { + $lastN: { + input: "$promotionEvents.promotionalDates.startDate", + n: 2 + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "e28fff9b-a8fb-4ac9-bb37-dea60d2a7d32", + "storeName": "Lakeshore Retail | Outdoor Furniture Collection - Erdmanside", + "lastTwoPromotions": [ + "Big Bargain Bash", + "Spectacular Savings Showcase" + ], + "lastTwoPromotionDates": [ + { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + { + "Year": 2024, + "Month": 6, + "Day": 23 + } + ] + }, + { + "_id": "1bec7539-dc75-4f7e-b4e8-afdf8ff2f234", + "storeName": "Adatum Corporation | Health Food Market - East Karina", + "lastTwoPromotions": [ + "Price Slash Spectacular", + "Spectacular Savings Showcase" + ], + "lastTwoPromotionDates": [ + { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + { + "Year": 2024, + "Month": 6, + "Day": 23 + } + ] + } +] +``` + +### Example 2: Use $lastN as accumulator to find the three highest selling categories of sales + +To retrieve the highest selling sales categories per store, run a query to sort sales categories in ascending order of sales volume, group the sorted results by store and return the last three categories per store. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $sort: { + "sales.salesByCategory.totalSales": 1 + } + }, + { + $group: { + _id: "$_id", + storeName: { + $last: "$name" + }, + top3Categories: { + $lastN: { + input: "$sales.salesByCategory.categoryName", + n: 3 + } + }, + top3SalesAmounts: { + $lastN: { + input: "$sales.salesByCategory.totalSales", + n: 3 + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "22e6367e-8341-415f-9795-118d2b522abf", + "storeName": "Adatum Corporation | Outdoor Furniture Mart - Port Simone", + "top3Categories": [ + "Outdoor Benches" + ], + "top3SalesAmounts": [ + 4976 + ] + }, + { + "_id": "a00a3ccd-49a2-4e43-b0d9-e56b96113ed0", + "storeName": "Wide World Importers | Smart Home Deals - Marcuschester", + "top3Categories": [ + "Smart Thermostats", + "Smart Plugs" + ], + "top3SalesAmounts": [ + 38696, + 633 + ] + } +] +``` + +### Example 3: Use $lastN operator as array-expression to get last two promotion events + +The example demonstrates the operator usage to find the last or most recent two promotion events from a store. + +```javascript +db.stores.aggregate([ + { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} }, + { + $project: { + name: 1, + lastTwoPromotions: { + $lastN: { + input: "$promotionEvents", + n: 2 + } + } + } + } +]) +``` + +This query returns the following result. + +```json +[ + { + "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74", + "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", + "lastTwoPromotions": [ + { + "eventName": "Grand Deal Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + }, + "endDate": { + "Year": 2024, + "Month": 6, + "Day": 30 + } + }, + "discounts": [ + { + "categoryName": "Remote Controls", + "discountPercentage": 7 + }, + { + "categoryName": "Televisions", + "discountPercentage": 11 + }, + { + "categoryName": "Business Projectors", + "discountPercentage": 13 + }, + { + "categoryName": "Laser Projectors", + "discountPercentage": 6 + }, + { + "categoryName": "Projectors", + "discountPercentage": 6 + }, + { + "categoryName": "Projector Screens", + "discountPercentage": 24 + } + ] + }, + { + "eventName": "Major Bargain Bash", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + }, + "endDate": { + "Year": 2024, + "Month": 9, + "Day": 30 + } + }, + "discounts": [ + { + "categoryName": "Sound Bars", + "discountPercentage": 9 + }, + { + "categoryName": "VR Games", + "discountPercentage": 7 + }, + { + "categoryName": "Xbox Games", + "discountPercentage": 25 + }, + { + "categoryName": "Projector Accessories", + "discountPercentage": 18 + }, + { + "categoryName": "Mobile Games", + "discountPercentage": 8 + }, + { + "categoryName": "Projector Cases", + "discountPercentage": 22 + } + ] + } + ] + } +] +``` diff --git a/reference/operators/accumulators/$max.md b/reference/operators/accumulators/$max.md new file mode 100644 index 0000000..0255ba5 --- /dev/null +++ b/reference/operators/accumulators/$max.md @@ -0,0 +1,432 @@ +--- +title: $max +description: The $max operator returns the maximum value from a set of input values. +type: operators +category: accumulators +--- + +# $max + +The `$max` operator returns the maximum value of a set of input values. + +When used as a field update operator, the `$max` operator updates the value of a field to a specified value if the specified value is greater than the current value of the field. If the field does not exist, `$max` creates the field and sets it to the specified value. + +## Syntax + +```javascript +$max: +``` + +When used as a field update operator: + +```javascript +{ + $max: { + : , + : , + ... + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **``** | Any valid expression that resolves to a value. The `$max` operator evaluates this expression to determine the maximum value. | + +When used as a field update operator: + +| Parameter | Description | +| --- | --- | +| **`field`** | The name of the field to update with the maximum value. | +| **`value`** | The value to compare with the current field value. The field will be updated only if this value is larger. | + +## 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 highest sales by category + +To calculate the highest sales within each category, first run a query to group all documents by sales category. Then run a $max query to retrieve the highest sales within each category across all stores. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $group: { + _id: "$sales.salesByCategory.categoryName", + maxSales: { + $max: "$sales.salesByCategory.totalSales" + } + } + } +]) +``` + +The first five results returned by this query are: + +```json +[ + { + "_id": "Christmas Trees", + "maxSales": 49697 + }, + { + "_id": "Nuts", + "maxSales": 48020 + }, + { + "_id": "Camping Tables", + "maxSales": 48568 + }, + { + "_id": "Music Theory Books", + "maxSales": 46133 + }, + { + "_id": "Fortified Wine", + "maxSales": 49912 + } +] +``` + +### Example 2: Using `$max` in `$bucket` + +To retrieve the highest sales within buckets of sales boundaries: + +```javascript +db.stores.aggregate([{ + $bucket: { + groupBy: "$sales.totalSales", + boundaries: [0, 1000, 5000, 10000], + default: "Other", + output: { + maxSales: { + $max: "$sales.totalSales" + } + } + } +}]) +``` + +This query returns the following results: + +```json +[ + { + "_id": 1000, + "maxSales": 4996 + }, + { + "_id": "Other", + "maxSales": 404106 + }, + { + "_id": 0, + "maxSales": 995 + }, + { + "_id": 5000, + "maxSales": 9999 + } +] +``` + +### Example 3: Using `$max` in `$setWindowFields` + +To get the highest discount for laptops in 2023, first run a query to unwind just promotion events and filter on the chosen category. Then partition the resulting documents by company and calculate the highest discount percentage within each resulting partition. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + // Filter only Laptops category and events in 2023 + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023, + "promotionEvents.discounts.categoryName": "Laptops" + } + }, + // Use $setWindowFields to calculate average discount by city + { + $setWindowFields: { + partitionBy: "$company", + output: { + maxDiscount: { + $max: "$promotionEvents.discounts.discountPercentage", + window: { + documents: ["unbounded", "unbounded"] + } + } + } + } + }, + // Group by city to return one result per city + { + $group: { + _id: "$company", + maxDiscount: { + $first: "$maxDiscount" + } + } + } +]) +``` + +The first three results returned by this query are: + +```json +[ + { + "_id": "Proseware, Inc.", + "maxDiscount": 24 + }, + { + "_id": "Fabrikam, Inc.", + "maxDiscount": 23 + }, + { + "_id": "Contoso, Ltd.", + "maxDiscount": 24 + } +] +``` + +### Example 4: Setting maximum staff capacity (field update operator) + +To update the full time staff to 10 only if the current full time staff count is lower, use the $max operator on the field to perform the update. Since the current `fullTime` value is 3, and 10 is greater than 3, the field will be updated to 10. + +```javascript +db.stores.updateOne( + { _id: "f2a8c190-28e4-4e14-9d8b-0256e53dca66" }, + { + $max: { + "staff.totalStaff.fullTime": 10 + } + } +) +``` + +### Example 5: Multiple field updates (field update operator) + +To update multiple fields with maximum values, use the $max operator with multiple fields and their corresponding max values to set. + +```javascript +db.stores.updateOne( + { _id: "f2a8c190-28e4-4e14-9d8b-0256e53dca66" }, + { + $max: { + "staff.totalStaff.partTime": 1, + "sales.totalSales": 50000 + } + } +) +``` + +In this case: + +- `partTime` (2) will remain 2 since 1 < 2 (no change) +- `totalSales` (31211) will be updated to 50000 since 50000 > 31211 + +### Example 6: Creating new fields (field update operator) + +If a field doesn't exist, `$max` creates it with the specified value. + +```javascript +db.stores.updateOne( + { _id: "f2a8c190-28e4-4e14-9d8b-0256e53dca66" }, + { + $max: { + "staff.maxStaffCapacity": 25, + "sales.peakSalesRecord": 100000 + } + } +) +``` + +### Example 7: Updating array elements (field update operator) + +Update maximum values within array elements using positional operators. + +```javascript +db.stores.updateOne( + { + _id: "f2a8c190-28e4-4e14-9d8b-0256e53dca66", + "sales.salesByCategory.categoryName": "Phone Mounts" + }, + { + $max: { + "sales.salesByCategory.$.totalSales": 12000 + } + } +) +``` + +### Example 8: Tracking peak performance (field update operator) + +Set peak performance metrics that only update when exceeded. + +```javascript +db.stores.updateOne( + { _id: "f2a8c190-28e4-4e14-9d8b-0256e53dca66" }, + { + $max: { + "performance.peakDailySales": 5000, + "performance.maxCustomersPerDay": 150, + "performance.highestSalesMonth": 45000 + } + } +) +``` + +After these field update operations, the updated document is: + +```json +{ + "_id": "f2a8c190-28e4-4e14-9d8b-0256e53dca66", + "name": "Fabrikam, Inc. | Car Accessory Outlet - West Adele", + "staff": { + "totalStaff": { + "fullTime": 10, + "partTime": 2 + }, + "maxStaffCapacity": 25 + }, + "sales": { + "totalSales": 50000, + "peakSalesRecord": 100000, + "salesByCategory": [ + { + "categoryName": "Phone Mounts", + "totalSales": 12000 + }, + { + "categoryName": "Dash Cameras", + "totalSales": 22300 + } + ] + }, + "performance": { + "peakDailySales": 5000, + "maxCustomersPerDay": 150, + "highestSalesMonth": 45000 + }, + "lastPromotionDate": ISODate("2024-12-31T00:00:00.000Z"), + "inventoryDeadline": ISODate("2024-06-30T00:00:00.000Z") +} +``` diff --git a/reference/operators/accumulators/$maxn.md b/reference/operators/accumulators/$maxn.md new file mode 100644 index 0000000..e3153b5 --- /dev/null +++ b/reference/operators/accumulators/$maxn.md @@ -0,0 +1,255 @@ +--- +title: $maxN +description: Retrieves the top N values based on a specified filtering criteria +type: operators +category: accumulators +--- + +# $maxN + +The `$maxN` operator is used to retrieve the top N values for a field based on a specified filtering criteria. + +## Syntax + +```javascript +$maxN: { + input: < field or expression > , + n: < number of values to retrieve > +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | Specifies the field or expression to evaluate for maximum values. | +| **`n`** | Specifies the number of maximum values to retrieve. Must be a positive integer. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5", + "name": "Lakeshore Retail | DJ Equipment Stop - Port Cecile", + "location": { + "lat": 60.1441, + "lon": -141.5012 + }, + "staff": { + "totalStaff": { + "fullTime": 2, + "partTime": 0 + } + }, + "sales": { + "salesByCategory": [ + { + "categoryName": "DJ Headphones", + "totalSales": 35921 + } + ], + "fullSales": 3700 + }, + "promotionEvents": [ + { + "eventName": "Bargain Blitz Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 3, + "Day": 11 + }, + "endDate": { + "Year": 2024, + "Month": 2, + "Day": 18 + } + }, + "discounts": [ + { + "categoryName": "DJ Turntables", + "discountPercentage": 18 + }, + { + "categoryName": "DJ Mixers", + "discountPercentage": 15 + } + ] + } + ], + "tag": [ + "#ShopLocal", + "#SeasonalSale", + "#FreeShipping", + "#MembershipDeals" + ], + "company": "Lakeshore Retail", + "city": "Port Cecile", + "lastUpdated": { + "$date": "2024-12-11T10:21:58.274Z" + } +} +``` + +### Example 1: Use `$maxN` as `accumulator` to retrieve top two sales categories + +This query retrieves the top two sales categories with the high-performing categories or aggregate top categories across stores. + +```javascript +db.stores.aggregate([{ + $project: { + topSalesCategories: { + $maxN: { + input: "$sales.salesByCategory", + n: 2 + } + } + } + }, + { + $limit: 4 + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "topSalesCategories": [ + { + "categoryName": "Stockings", + "totalSales": 25731 + } + ] + }, + { + "_id": "7e53ca0f-6e24-4177-966c-fe62a11e9af5", + "topSalesCategories": [ + { + "categoryName": "Markers", + "totalSales": 3927 + } + ] + }, + { + "_id": "44fdb9b9-df83-4492-8f71-b6ef648aa312", + "topSalesCategories": [ + { + "categoryName": "Storage Boxes", + "totalSales": 2236 + } + ] + }, + { + "_id": "94792a4c-4b03-466b-91f6-821c4a8b2aa4", + "topSalesCategories": [ + { + "categoryName": "Travel Backpacks", + "totalSales": 13189 + }, + { + "categoryName": "Suitcases", + "totalSales": 37858 + } + ] + } +] +``` + +### Example 2: Using `$maxN` in `$setWindowFields` + +This query retrieves the top N discounts for "Laptops" in 2023 per city. This query filters for "Laptops" discount entries in 2023 and then groups the resulting documents by city. + +```javascript +db.stores.aggregate([ + { $unwind: "$promotionEvents" }, + { $unwind: "$promotionEvents.discounts" }, + { + $match: { + "promotionEvents.discounts.categoryName": "Laptops", + "promotionEvents.promotionalDates.startDate.Year": 2023 + } + }, + { + $group: { + _id: "$city", + allDiscounts: { + $push: "$promotionEvents.discounts.discountPercentage" + } + } + }, + { + $project: { + topDiscounts: { + $slice: [ + { $sortArray: { input: "$allDiscounts", sortBy: -1 } }, + 3 // Top N discounts + ] + } + } + } +]) +``` + +The first three results returned by this query are: + +```json +[ + { + "_id": "Lake Margareteland", + "topDiscounts": [ + 18 + ] + }, + { + "_id": "Horacetown", + "topDiscounts": [ + 13 + ] + }, + { + "_id": "D'Amoreside", + "topDiscounts": [ + 9 + ] + } +] +``` + +### Example 3: Using `$maxN` operator as array-expression to find top three sales categories + +This query retrieves the top three sales values from all sales categories. + +```javascript +db.stores.aggregate([ + { $match: {"_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} }, + { + $project: { + name: 1, + topThreeSales: { + $maxN: { + input: "$sales.salesByCategory.totalSales", + n: 3 + } + } + } + } +]) +``` + +This query returns the following result. + +```json +[ + { + "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74", + "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", + "topThreeSales": [43522, 32272, 28946] + } +] +``` diff --git a/reference/operators/accumulators/$median.md b/reference/operators/accumulators/$median.md new file mode 100644 index 0000000..ae2df0f --- /dev/null +++ b/reference/operators/accumulators/$median.md @@ -0,0 +1,193 @@ +--- +title: $median +description: The $median operator calculates the median value of a numeric field in a group of documents. +type: operators +category: accumulators +--- + +# $median usage on DocumentDB + +The `$median` accumulator operator calculates the median value of a numeric field in a group of documents. + +## Syntax + +```javascript +{ + $group: { + _id: < expression > , + medianValue: { + $median: { + input: < field or expression > , + method: < > + } + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **``** | The field or expression from which to calculate the median. | + +## 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 median sales volume + +To calculate the median sales volume within each category, first group the documents by the distinct sales categories, then calculate the median sales within each grouped category. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" +}, { + $group: { + _id: "$sales.salesByCategory.categoryName", + medianSales: { + $median: { + "input": "$sales.salesByCategory.totalSales", + "method": "approximate" + } + } + } +}]) +``` + +The first five results returned by this query are: + +```json +[ + { + "_id": "Light Bulbs", + "medianSales": 24845 + }, + { + "_id": "Christmas Trees", + "medianSales": 28210 + }, + { + "_id": "Ukuleles", + "medianSales": 27295 + }, + { + "_id": "GPUs", + "medianSales": 19813 + }, + { + "_id": "Towels", + "medianSales": 27771 + } +] +``` diff --git a/reference/operators/accumulators/$min.md b/reference/operators/accumulators/$min.md new file mode 100644 index 0000000..a2524b2 --- /dev/null +++ b/reference/operators/accumulators/$min.md @@ -0,0 +1,485 @@ +--- +title: $min +description: Retrieves the minimum value for a specified field +type: operators +category: accumulators +--- + +# $min + +The `$min` operator is used within aggregation stages like `$group`, `$bucket`, `$bucketAuto`, or `$setWindowFields`. The min operator is particularly useful in summarizing data or finding the smallest value in a dataset. + +When used as a field update operator, `$min` operator updates the value of a field to a specified value if the specified value is less than the current value of the field. If the field does not exist, `$min` creates the field and sets it to the specified value. + +## Syntax + +```javascript +$min: +``` + +The `` can be a field path or an aggregation expression that specifies the values to be considered for the minimum calculation. + +As a field update operator: + +```javascript +{ + $min: { + : , + : , + ... + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **``** | Specifies the field or computed value to determine the minimum value. | + +As a field update operator: + +| Parameter | Description | +| --- | --- | +| **`field`** | The name of the field to update with the minimum value. | +| **`value`** | The value to compare with the current field value. The field will be updated only if this value is smaller. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5", + "name": "Lakeshore Retail | DJ Equipment Stop - Port Cecile", + "location": { + "lat": 60.1441, + "lon": -141.5012 + }, + "staff": { + "totalStaff": { + "fullTime": 2, + "partTime": 0 + } + }, + "sales": { + "salesByCategory": [ + { + "categoryName": "DJ Headphones", + "totalSales": 35921 + } + ], + "fullSales": 3700 + }, + "promotionEvents": [ + { + "eventName": "Bargain Blitz Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 3, + "Day": 11 + }, + "endDate": { + "Year": 2024, + "Month": 2, + "Day": 18 + } + }, + "discounts": [ + { + "categoryName": "DJ Turntables", + "discountPercentage": 18 + }, + { + "categoryName": "DJ Mixers", + "discountPercentage": 15 + } + ] + } + ], + "tag": [ + "#ShopLocal", + "#SeasonalSale", + "#FreeShipping", + "#MembershipDeals" + ], + "company": "Lakeshore Retail", + "city": "Port Cecile", + "lastUpdated": { + "$date": "2024-12-11T10:21:58.274Z" + } +} +``` + +### Example 1: Using `$min` in `$group` + +This query calculates the minimum sales value for each category in the `sales.salesByCategory` array by first grouping documents by sales category and then calculating the minimum sales volume within each category. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $group: { + _id: "$sales.salesByCategory.categoryName", + minSales: { + $min: "$sales.salesByCategory.totalSales" + } + } + } +]) +``` + +This query returns the following results. + +```json +[ + { + "_id": "Christmas Trees", + "minSales": 391 + }, + { + "_id": "Nuts", + "minSales": 257 + }, + { + "_id": "Camping Tables", + "minSales": 171 + }, + { + "_id": "Music Theory Books", + "minSales": 323 + }, + { + "_id": "Fortified Wine", + "minSales": 521 + }, + { + "_id": "Children's Mystery", + "minSales": 1470 + }, + { + "_id": "Short Throw Projectors", + "minSales": 111 + }, + { + "_id": "Pliers", + "minSales": 1981 + }, + { + "_id": "Bluetooth Headphones", + "minSales": 465 + }, + { + "_id": "Video Storage", + "minSales": 1568 + }, + { + "_id": "Cleansers", + "minSales": 170 + }, + { + "_id": "Camera Straps", + "minSales": 127 + }, + { + "_id": "Carry-On Bags", + "minSales": 149 + }, + { + "_id": "Disinfectant Wipes", + "minSales": 647 + }, + { + "_id": "Insignia Smart TVs", + "minSales": 451 + }, + { + "_id": "Toner Refill Kits", + "minSales": 3525 + }, + { + "_id": "iPads", + "minSales": 325 + }, + { + "_id": "Storage Baskets", + "minSales": 1151 + }, + { + "_id": "Memory Foam Mattresses", + "minSales": 422 + }, + { + "_id": "Body Spray", + "minSales": 448 + } +] +``` + +### Example 2: Using `$min` in `$bucket` + +This query creates buckets based on sales values and calculates the minimum sales value for each bucket. + +```javascript +db.stores.aggregate([{ + $bucket: { + groupBy: "$sales.totalSales", + boundaries: [0, 1000, 5000, 10000], + default: "Other", + output: { + minSales: { + $min: "$sales.totalSales" + } + } + } +}]) +``` + +This query returns the following results. + +```json +[ + { + "_id": 1000, + "minSales": 1000 + }, + { + "_id": "Other", + "minSales": null + }, + { + "_id": 0, + "minSales": 108 + }, + { + "_id": 5000, + "minSales": 5001 + } +] +``` + +### Example 3: Using `$min` in `$setWindowFields` + +This query retrieves the minimum discount for "Laptops" by company, in the year 2023: + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + + // Filter only Laptops category and events in 2023 + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023, + "promotionEvents.discounts.categoryName": "Laptops" + } + }, + + // Use $setWindowFields to calculate average discount by city + { + $setWindowFields: { + partitionBy: "$company", + output: { + minDiscount: { + $min: "$promotionEvents.discounts.discountPercentage", + window: { + documents: ["unbounded", "unbounded"] + } + } + } + } + }, + + // Group by city to return one result per city + { + $group: { + _id: "$company", + minDiscount: { + $first: "$minDiscount" + } + } + } +]) +``` + +This query returns the following results. + +```json +[ + { + "_id": "VanArsdel, Ltd.", + "minDiscount": 6 + }, + { + "_id": "Proseware, Inc.", + "minDiscount": 8 + }, + { + "_id": "Fabrikam, Inc.", + "minDiscount": 5 + }, + { + "_id": "Contoso, Ltd.", + "minDiscount": 5 + }, + { + "_id": "Fourth Coffee", + "minDiscount": 6 + }, + { + "_id": "Trey Research", + "minDiscount": 7 + }, + { + "_id": "Adatum Corporation", + "minDiscount": 5 + }, + { + "_id": "Relecloud", + "minDiscount": 5 + }, + { + "_id": "Lakeshore Retail", + "minDiscount": 7 + }, + { + "_id": "Northwind Traders", + "minDiscount": 8 + }, + { + "_id": "First Up Consultants", + "minDiscount": 9 + }, + { + "_id": "Wide World Importers", + "minDiscount": 10 + }, + { + "_id": "Tailwind Traders", + "minDiscount": 5 + } +] +``` + +### Example 4: Setting minimum staff requirements (field update operator) + +To set a minimum staff requirement, update the full time stagg count only if the current value of the field is higher. Since the current `fullTime` value is 14, and 10 is less than 14, the field will be updated to 10. + +```javascript +db.stores.updateOne( + { _id: "26afb024-53c7-4e94-988c-5eede72277d5" }, + { + $min: { + "staff.totalStaff.fullTime": 10 + } + } +) +``` + +### Example 5: Multiple field updates (field update operator) + +To update multiple fields with minimum values simultaneously, use the $min operator with multiple fields and corresponding min values. + +```javascript +db.stores.updateOne( + { _id: "26afb024-53c7-4e94-988c-5eede72277d5" }, + { + $min: { + "staff.totalStaff.partTime": 12, + "sales.totalSales": 50000 + } + } +) +``` + +In this case: + +- `partTime` (8) will be updated to 8 since 12 > 8 (no change) +- `totalSales` (83865) will be updated to 50000 since 50000 < 83865 + +### Example 6: Creating new fields (field update operator) + +If a field doesn't exist, `$min` creates it with the specified value. + +```javascript +db.stores.updateOne( + { _id: "26afb024-53c7-4e94-988c-5eede72277d5" }, + { + $min: { + "staff.minStaffRequired": 15, + "sales.minimumSalesTarget": 30000 + } + } +) +``` + +### Example 7: Working with Dates (field update operator) + +Set minimum dates for tracking earliest events. + +```javascript +db.stores.updateOne( + { _id: "26afb024-53c7-4e94-988c-5eede72277d5" }, + { + $min: { + "lastInventoryCheck": new Date("2024-01-15"), + "firstSaleDate": new Date("2023-06-01") + } + } +) +``` + +### Example 8: Updating array elements (field update operator) + +Update minimum values within array elements using positional operators. + +```javascript +db.stores.updateOne( + { + _id: "26afb024-53c7-4e94-988c-5eede72277d5", + "sales.salesByCategory.categoryName": "Lavalier Microphones" + }, + { + $min: { + "sales.salesByCategory.$.totalSales": 40000 + } + } +) +``` + +After these field update operations, the updated document is: + +```json +{ + "_id": "26afb024-53c7-4e94-988c-5eede72277d5", + "name": "First Up Consultants | Microphone Bazaar - South Lexusland", + "staff": { + "totalStaff": { + "fullTime": 10, + "partTime": 8 + }, + "minStaffRequired": 15 + }, + "sales": { + "totalSales": 50000, + "minimumSalesTarget": 30000, + "salesByCategory": [ + { + "categoryName": "Lavalier Microphones", + "totalSales": 40000 + }, + { + "categoryName": "Wireless Microphones", + "totalSales": 39691 + } + ] + }, + "lastInventoryCheck": ISODate("2024-01-15T00:00:00.000Z"), + "firstSaleDate": ISODate("2023-06-01T00:00:00.000Z") +} +``` diff --git a/reference/operators/accumulators/$minn.md b/reference/operators/accumulators/$minn.md new file mode 100644 index 0000000..a2e91a6 --- /dev/null +++ b/reference/operators/accumulators/$minn.md @@ -0,0 +1,308 @@ +--- +title: $minN +description: Retrieves the bottom N values based on a specified filtering criteria +type: operators +category: accumulators +--- + +# $minN + +The `$minN` operator is used to retrieve the bottom N values for a field based on a specified filtering criteria. + +## Syntax + +```javascript +$minN: { + input: < field or expression > , + n: < number of values to retrieve > +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | Specifies the field or expression to evaluate for minimum values. | +| **`n`** | Specifies the number of minimum values to retrieve. Must be a positive integer. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "7954bd5c-9ac2-4c10-bb7a-2b79bd0963c5", + "name": "Lakeshore Retail | DJ Equipment Stop - Port Cecile", + "location": { + "lat": 60.1441, + "lon": -141.5012 + }, + "staff": { + "totalStaff": { + "fullTime": 2, + "partTime": 0 + } + }, + "sales": { + "salesByCategory": [ + { + "categoryName": "DJ Headphones", + "totalSales": 35921 + } + ], + "fullSales": 3700 + }, + "promotionEvents": [ + { + "eventName": "Bargain Blitz Days", + "promotionalDates": { + "startDate": { + "Year": 2024, + "Month": 3, + "Day": 11 + }, + "endDate": { + "Year": 2024, + "Month": 2, + "Day": 18 + } + }, + "discounts": [ + { + "categoryName": "DJ Turntables", + "discountPercentage": 18 + }, + { + "categoryName": "DJ Mixers", + "discountPercentage": 15 + } + ] + } + ], + "tag": [ + "#ShopLocal", + "#SeasonalSale", + "#FreeShipping", + "#MembershipDeals" + ], + "company": "Lakeshore Retail", + "city": "Port Cecile", + "lastUpdated": { + "$date": "2024-12-11T10:21:58.274Z" + } +} +``` + +### Example 1: Retrieve bottom two sales categories + +This query retrieves the bottom two sales categories per store with the lowest sales volume. Run a query using the $minN operator on the nested salesCategory field. + +```javascript +db.stores.aggregate([{ + $project: { + bottomSalesCategories: { + $minN: { + input: "$sales.salesByCategory", + n: 2 + } + } + } + }, + { + $limit: 4 + } +]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "a715ab0f-4c6e-4e9d-a812-f2fab11ce0b6", + "bottomSalesCategories": [ + { + "categoryName": "Stockings", + "totalSales": 25731 + } + ] + }, + { + "_id": "923d2228-6a28-4856-ac9d-77c39eaf1800", + "bottomSalesCategories": [ + { + "categoryName": "Lamps", + "totalSales": 19880 + }, + { + "categoryName": "Rugs", + "totalSales": 20055 + } + ] + }, + { + "_id": "7e53ca0f-6e24-4177-966c-fe62a11e9af5", + "bottomSalesCategories": [ + { + "categoryName": "Markers", + "totalSales": 3927 + } + ] + }, + { + "_id": "44fdb9b9-df83-4492-8f71-b6ef648aa312", + "bottomSalesCategories": [ + { + "categoryName": "Storage Boxes", + "totalSales": 2236 + } + ] + } +] +``` + +### Example 2 - Using $minN with $setWindowFields + +To get the bottom two lists of sales categories by sales volume across all stores within the "First Up Consultants" company, first run a query to partition the stores by the company. Then, use the $minN operator to determine the two categories with the lowest sales within each partition. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $setWindowFields: { + partitionBy: "$company", + sortBy: { + "sales.totalSales": -1 + }, + output: { + minTwoBySales: { + $minN: { + input: "$sales.totalSales", + n: 2 + } + } + } + } +}, { + $project: { + company: 1, + name: 1, + minCategoriesBySales: 1 + } +}]) +``` + +The first result returned by this query is: + +```json +[ + { + "_id": "a0386810-b6f8-4b05-9d60-e536fb2b0026", + "name": "First Up Consultants | Electronics Stop - South Thelma", + "company": "First Up Consultants", + "minCategoriesBySales": [ + [ + { + "categoryName": "3D Printers", + "totalSales": 20882 + }, + { + "categoryName": "Phone Mounts", + "totalSales": 13624 + }, + { + "categoryName": "Prepaid Phones", + "totalSales": 7182 + }, + { + "categoryName": "MacBooks", + "totalSales": 10541 + }, + { + "categoryName": "Chargers", + "totalSales": 37542 + }, + { + "categoryName": "Student Laptops", + "totalSales": 43977 + }, + { + "categoryName": "Screen Protectors", + "totalSales": 14648 + }, + { + "categoryName": "Photo Printers", + "totalSales": 40064 + }, + { + "categoryName": "Printer Ink", + "totalSales": 30784 + }, + { + "categoryName": "Smartphone Cases", + "totalSales": 30468 + }, + { + "categoryName": "Printer Drums", + "totalSales": 34980 + }, + { + "categoryName": "Desktops", + "totalSales": 3890 + } + ], + [ + { + "categoryName": "4K Camcorders", + "totalSales": 10466 + }, + { + "categoryName": "Tripods", + "totalSales": 30942 + }, + { + "categoryName": "Camcorder Accessories", + "totalSales": 25601 + } + ] + ] + } +] +``` + +### Example 3 - Using $minN operator as array-expression to get lowest two sales values + +This query extracts the two lowest sales values for a specific store document. + +```javascript +db.stores.aggregate([ + { $match: {_id: "40d6f4d7-50cd-4929-9a07-0a7a133c2e74"} }, + { + $project: { + name: 1, + lowestTwoSales: { + $minN: { + input: "$sales.salesByCategory.totalSales", + n: 2 + } + } + } + } +]) +``` + +This query returns the following result. + +```json +[ + { + "_id": "40d6f4d7-50cd-4929-9a07-0a7a133c2e74", + "name": "Proseware, Inc. | Home Entertainment Hub - East Linwoodbury", + "lowestTwoSales": [28946, 3000] + } +] +``` diff --git a/reference/operators/accumulators/$percentile.md b/reference/operators/accumulators/$percentile.md new file mode 100644 index 0000000..c3dfb48 --- /dev/null +++ b/reference/operators/accumulators/$percentile.md @@ -0,0 +1,212 @@ +--- +title: $percentile +description: The $percentile operator calculates the percentile of numerical values that match a filtering criteria +type: operators +category: accumulators +--- + +# $percentile + +The `$percentile` operator calculates the percentile of numerical values that match a filtering criteria. This operator is particularly useful for identifying statistical thresholds, such as median or percentiles. + +## Syntax + +```javascript +$percentile: { + input: < field or expression > , + p: [ < percentile values > ], + method: < method > +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`input`** | Specifies the numerical data to calculate the percentile from. | +| **`p`** | An array of percentile values (between 0 and 1) to calculate. | +| **`method`** | Specifies the interpolation method to use. Valid values are `"approximate"` and `"continuous"`. | + +## 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 50th percentile of sales volume + +This query calculates the 50th percentile (median) of total sales volume within each sales category across all stores. + +```javascript +db.stores.aggregate([{ + $unwind: "$sales.salesByCategory" + }, + { + $group: { + _id: null, + medianSales: { + $percentile: { + input: "$sales.salesByCategory.totalSales", + p: [0.5], + method: "approximate" + } + } + } + } +]) +``` + +This query returns the following result: + +```json +[ + { + "_id": null, + "medianSales": [ + 25070.449624139295 + ] + } +] +``` + +### Example 2: Calculate multiple percentiles + +This query calculates the 25th, 50th, and 75th percentiles of the total sales across all stores. + +```javascript +db.stores.aggregate([{ + $group: { + _id: null, + percentiles: { + $percentile: { + input: "$sales.fullSales", + p: [0.25, 0.5, 0.75], + method: "approximate" + } + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": null, + "percentiles": [ + 3700, + 3700, + 3700 + ] + } +] +``` diff --git a/reference/operators/accumulators/$stddevpop.md b/reference/operators/accumulators/$stddevpop.md new file mode 100644 index 0000000..b1b8a47 --- /dev/null +++ b/reference/operators/accumulators/$stddevpop.md @@ -0,0 +1,284 @@ +--- +title: $stddevpop +description: The $stddevpop operator calculates the standard deviation of the specified values +type: operators +category: accumulators +--- + +# $stddevpop + +The `$stddevpop` operator calculates the standard deviation of the specified values. The operator can only calculate the standard deviation of numeric values. + +## Syntax + +```javascript +{ + $stddevpop: {fieldName} +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`fieldName`** | The field whose values are used to calculate the standard deviation| + +## 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 standard deviation of total sales + +To calculate the standard deviation of the total sales across all sales categories for stores belonging to "Fourth Coffee", first filter on the company field, then calculate the total sales across all resulting stores using stddevpop and return the aggregated result. + +```javascript +db.stores.aggregate([{ + $match: { + company: "Fourth Coffee" + } +}, { + $group: { + _id: "$company", + stdDev: { + $stdDevPop: "$sales.totalSales" + } + } +}])[{ + _id: 'Fourth Coffee', + stdDev: 0 +}] +``` + +This query returns the following result: + +```json +[ + { + "_id": "Fourth Coffee", + "stdDev": 39133.27057120701 + } +] +``` + +### Example 2 - Calculate the standard deviation of a field with a single value + +To calculate the standard deviation of a field with only one distinct value, the standard deviation is 0. This query groups documents corresponding to the "Fourth Company". Each store contains a single document and only one distinct value for total sales. + +```javascript +db.stores.aggregate([{ + $match: { + company: "Fourth Coffee" + } +}, { + $group: { + _id: "$name", + stdDev: { + $stdDevPop: "$sales.totalSales" + } + } +}]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "Fourth Coffee | Outdoor Equipment Collection - Kochview", + "stdDev": 0 + }, + { + "_id": "Fourth Coffee | Grocery Hub - Brakusborough", + "stdDev": 0 + }, + { + "_id": "Fourth Coffee | Pet Supply Nook - Lake Armanimouth", + "stdDev": 0 + }, + { + "_id": "Fourth Coffee | Beauty Product Nook - Emmytown", + "stdDev": 0 + }, + { + "_id": "Fourth Coffee | Bed and Bath Closet - Legroston", + "stdDev": 0 + }, + { + "_id": "Fourth Coffee | Automotive Part Collection - Cassinport", + "stdDev": 0 + } +] +``` + +### Example 3 - Calculate the standard deviation for a field when using window operators + +This query calculates the standard deviation of total sales for stores belonging to the "First Up Consultants" company from the first to the current document in the result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + }, + $and: [{ + lastUpdated: { + $gt: ISODate("2024-09-01T03:06:24.180Z") + } + }, { + lastUpdated: { + "$lt": ISODate("2025-09-30T03:55:17.557Z") + } + }] + } +}, { + $setWindowFields: { + partitionBy: "$company", + sortBy: { + lastUpdated: 1 + }, + output: { + stdDevPopTotalSales: { + $stdDevPop: "$sales.totalSales", + window: { + documents: ["unbounded", "current"] + } + } + } + } +}, { + $project: { + company: 1, + name: 1, + "sales.totalSales": 1, + lastUpdated: 1, + stdDevPopTotalSales: 1 + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "sales": {}, + "company": "First Up Consultants", + "lastUpdated": { + "$date": "2025-06-11T10:48:01.291Z" + }, + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "stdDevPopTotalSales": null + } +] +``` diff --git a/reference/operators/accumulators/$stddevsamp.md b/reference/operators/accumulators/$stddevsamp.md new file mode 100644 index 0000000..308e6ba --- /dev/null +++ b/reference/operators/accumulators/$stddevsamp.md @@ -0,0 +1,172 @@ +--- +title: $stddevsamp +description: The $stddevsamp operator calculates the standard deviation of a specified sample of values and not the entire population +type: operators +category: accumulators +--- + +# $stddevsamp + +The `$stddevsamp` operator calculates the standard deviation by taking a specified sample of the values of a field. The standard deviation is calculated by taking a random sample of the specified size. If a precise standard deviation is needed, $stdDevPop must be used instead. + +## Syntax + +```javascript +{ + $stddevsamp: {fieldName} +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`fieldName`** | The field whose values are used to calculate the standard deviation of the specified sample size| + +## 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 standard deviation of total sales + +This query calculates the standard deviation of total sales across stores in the "Fourth Coffee" company by taking a random sample of 10 documents matching the filtering criteria. + +```javascript +db.stores.aggregate([{ + $match: { + "company": "Fourth Coffee" + } +}, { + $sample: { + size: 10 + } +}, { + $group: { + _id: "$company", + stdDev: { + $stdDevSamp: "$sales.totalSales" + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "Fourth Coffee", + "stdDev": 22040.044055209048 + } +] +``` diff --git a/reference/operators/accumulators/$sum.md b/reference/operators/accumulators/$sum.md new file mode 100644 index 0000000..e8dfc39 --- /dev/null +++ b/reference/operators/accumulators/$sum.md @@ -0,0 +1,316 @@ +--- +title: $sum +description: The $sum operator calculates the sum of the values of a field based on a filtering criteria +type: operators +category: accumulators +--- + +# $sum + +The `$sum` operator calculates the sum of numeric values of a field or expression that match a filtering criteria. + +## Syntax + +```javascript +{ + $sum: +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **``** | The field or expression to calculate the sum of. This can be a field, a numeric value, or an expression. | + +## 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 `$sum` in `$group` + +To compute total discount percentage per category across all promotion events in 2023: + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023 + } + }, + { + $group: { + _id: "$promotionEvents.discounts.categoryName", + totalDiscountIn2023: { + $sum: "$promotionEvents.discounts.discountPercentage" + } + } + }, + { + $project: { + _id: 0, + categoryName: "$_id", + totalDiscountIn2023: 1 + } + } +]) +``` + +This query returns the following results: + +```json +[ + { + "categoryName": "Glass Frames", + "totalDiscountIn2023": 25 + }, + { + "categoryName": "Picture Hanging Supplies", + "totalDiscountIn2023": 14 + } +] +``` + +### Example 2: Using `$sum` in `$bucket` + +To get the total sales within defined sales boundaries: + +```javascript +db.stores.aggregate([{ + $bucket: { + groupBy: "$sales.totalSales", // Field to group by + boundaries: [0, 10000, 20000, 50000, 100000], // Sales ranges + default: "Other", // Default bucket for values outside the defined ranges + output: { + totalSalesSum: { + $sum: "$sales.totalSales" + }, // Sum the sales for each bucket + count: { + $sum: 1 + } // Count the number of documents in each bucket + } + } +}]) +``` + +This query returns the following results: + +```json +[ + { + "_id": "Other", + "totalSalesSum": 454981695, + "count": 3001 + }, + { + "_id": 0, + "totalSalesSum": 20033725, + "count": 3903 + }, + { + "_id": 10000, + "totalSalesSum": 71303703, + "count": 4712 + }, + { + "_id": 50000, + "totalSalesSum": 756168541, + "count": 11025 + }, + { + "_id": 20000, + "totalSalesSum": 678976078, + "count": 18861 + } +] +``` + +### Example 3: Using `$sum` in `$setWindowFields` + +To calculate the total discount per sales category for promotions in 2023: + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + { + $match: { + "promotionEvents.promotionalDates.startDate.Year": 2023 + } + }, + { + $setWindowFields: { + partitionBy: "$promotionEvents.discounts.categoryName", // Group by categoryName + output: { + totalDiscountIn2023: { + $sum: "$promotionEvents.discounts.discountPercentage", // Sum discount percentage + window: { + documents: ["unbounded", "unbounded"] // Aggregate over all documents in the partition + } + } + } + } + }, + { + $project: { + _id: 0, + categoryName: "$promotionEvents.discounts.categoryName", + discountPercentage: "$promotionEvents.discounts.discountPercentage", + totalDiscountIn2023: 1 + } + }, + { + $limit: 5 + } +]) +``` + +This query returns the following results: + +```json +[ + { + "totalDiscountIn2023": 1106, + "categoryName": "2-in-1 Laptops", + "discountPercentage": 25 + }, + { + "totalDiscountIn2023": 1106, + "categoryName": "2-in-1 Laptops", + "discountPercentage": 22 + }, + { + "totalDiscountIn2023": 1106, + "categoryName": "2-in-1 Laptops", + "discountPercentage": 19 + }, + { + "totalDiscountIn2023": 1106, + "categoryName": "2-in-1 Laptops", + "discountPercentage": 17 + }, + { + "totalDiscountIn2023": 1106, + "categoryName": "2-in-1 Laptops", + "discountPercentage": 10 + } +] +``` diff --git a/reference/operators/accumulators/$top.md b/reference/operators/accumulators/$top.md new file mode 100644 index 0000000..9e342ff --- /dev/null +++ b/reference/operators/accumulators/$top.md @@ -0,0 +1,288 @@ +--- +title: $top +description: The $top operator returns the first document from the result set sorted by one or more fields +type: operators +category: accumulators +--- + +# $top + +The `$top` operator sorts documents on one or more fields specified by the query and returns the first document matching the filtering criteria. It combines sorting and selection in a single operation, making it efficient for finding the highest or lowest values without requiring a separate sort stage. + +## Syntax + +```javascript +{ + $top: { + output: [listOfFields], + sortBy: { + < fieldName >: < sortOrder > + } + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`listOfFields`** | The list of fields to be returned for the last document in the result set| +| **`fieldName`** | The field to use for sorting the result set| +| **`sortOrder`** | 1 or -1. 1 implies sorting in ascending order of the value of the field while -1 implies sorting in descending order of the values of the field| + +## 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: Get the top selling category per store + +To find the highest-selling category within the First Up Consultants company, run a query to retrieve stores within the company, sort the documents in descending order of total sales within each category and return the top document in the sorted result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $group: { + _id: "$company", + topSales: { + $top: { + output: ["$company", "$sales"], + sortBy: { + "sales.totalSales": -1 + } + } + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "topSales": [ + "First Up Consultants", + { + "salesByCategory": [ + { + "categoryName": "Towel Sets", + "totalSales": 520 + }, + { + "categoryName": "Bath Accessories", + "totalSales": 41710 + }, + { + "categoryName": "Drapes", + "totalSales": 42893 + }, + { + "categoryName": "Towel Racks", + "totalSales": 30773 + }, + { + "categoryName": "Hybrid Mattresses", + "totalSales": 39491 + }, + { + "categoryName": "Innerspring Mattresses", + "totalSales": 6410 + }, + { + "categoryName": "Bed Frames", + "totalSales": 41917 + }, + { + "categoryName": "Mattress Protectors", + "totalSales": 44124 + }, + { + "categoryName": "Bath Towels", + "totalSales": 5671 + }, + { + "categoryName": "Turkish Towels", + "totalSales": 25674 + } + ], + "revenue": 279183 + } + ] + } +] +``` + +### Example 2: Get the highest discount by promotion category + +To fetch the highest discount per sales category, first run a query to group all documents by store, then sort the documents in descending order of discount percentages within each promotion event and return the top document from the sorted result set per store. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $unwind: "$promotionEvents.discounts" + }, + { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + highestDiscount: { + $top: { + sortBy: { + "promotionEvents.discounts.discountPercentage": -1 + }, + output: { + categoryName: "$promotionEvents.discounts.categoryName", + discountPercentage: "$promotionEvents.discounts.discountPercentage", + eventName: "$promotionEvents.eventName" + } + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "64ec6589-068a-44a6-be5b-9d37bb0a90f1", + "storeName": "First Up Consultants | Computer Gallery - West Cathrine", + "highestDiscount": { + "categoryName": "Gaming Accessories", + "discountPercentage": 24, + "eventName": "Crazy Markdown Madness" + } + }, + { + "_id": "a58d0356-493b-44e6-afab-260aa3296930", + "storeName": "Fabrikam, Inc. | Outdoor Furniture Nook - West Lexie", + "highestDiscount": { + "categoryName": "Fire Pits", + "discountPercentage": 22, + "eventName": "Savings Showdown" + } + } +] +``` diff --git a/reference/operators/accumulators/$topn.md b/reference/operators/accumulators/$topn.md new file mode 100644 index 0000000..daa5d07 --- /dev/null +++ b/reference/operators/accumulators/$topn.md @@ -0,0 +1,327 @@ +--- +title: $topN +description: The $topN operator returns the first N documents from the result sorted by one or more fields +type: operators +category: accumulators +--- + +# $topN + +The `$topN` operator sorts documents on one or more fields specified by the query and returns the first N documents matching the filtering criteria. It extends the functionality of `$top` by allowing you to retrieve multiple top elements instead of just the single highest-ranked item. + +## Syntax + +```javascript +{ + $topN: { + output: [listOfFields], + sortBy: { + : < sortOrder > + }, + n: < numDocumentsToReturn > + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`listOfFields`** | The list of fields to be returned for the last document in the result set| +| **`fieldName`** | The field to use for sorting the result set| +| **`sortOrder`** | 1 or -1. 1 implies sorting in ascending order of the value of the field while -1 implies sorting in descending order of the values of the field| +| **`n`** | The number of documents to return from the top of the sorted result set | + +## 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 - Get the two stores with the lowest total sales + +To get the two lowest stores by sales within the First Up Consultants company, run a query to filter on the company name, sort the resulting documents in ascending order of sales and return the top two documents from the sorted result set. + +```javascript +db.stores.aggregate([{ + $match: { + company: { + $in: ["First Up Consultants"] + } + } +}, { + $group: { + _id: "$company", + topSales: { + $topN: { + output: ["$company", "$sales"], + sortBy: { + "sales.totalSales": 1 + }, + n: 2 + } + } + } +}]) +``` + +This query returns the following result: + +```json +[ + { + "_id": "First Up Consultants", + "topSales": [ + [ + "First Up Consultants", + { + "salesByCategory": [ + { + "categoryName": "Towel Sets", + "totalSales": 520 + }, + { + "categoryName": "Bath Accessories", + "totalSales": 41710 + }, + { + "categoryName": "Drapes", + "totalSales": 42893 + }, + { + "categoryName": "Towel Racks", + "totalSales": 30773 + }, + { + "categoryName": "Hybrid Mattresses", + "totalSales": 39491 + }, + { + "categoryName": "Innerspring Mattresses", + "totalSales": 6410 + }, + { + "categoryName": "Bed Frames", + "totalSales": 41917 + }, + { + "categoryName": "Mattress Protectors", + "totalSales": 44124 + }, + { + "categoryName": "Bath Towels", + "totalSales": 5671 + }, + { + "categoryName": "Turkish Towels", + "totalSales": 25674 + } + ], + "revenue": 279183 + } + ], + [ + "First Up Consultants", + { + "salesByCategory": [ + { + "categoryName": "Lavalier Microphones", + "totalSales": 40000 + }, + { + "categoryName": "Wireless Microphones", + "totalSales": 39691 + } + ], + "minimumSalesTarget": 30000, + "revenue": 50000 + } + ] + ] + } +] +``` + +### Example 2: Get the two most recent promotion events + +To find the two most recent promotion events for each store, group the documents in collection by store, sort them in ascending order of promotion dates and return the top two results from the sorted result set per store. + +```javascript +db.stores.aggregate([{ + $unwind: "$promotionEvents" + }, + { + $group: { + _id: "$_id", + storeName: { + $first: "$name" + }, + top2RecentPromotions: { + $topN: { + n: 2, + sortBy: { + "promotionEvents.promotionalDates.startDate.Year": -1, + "promotionEvents.promotionalDates.startDate.Month": -1, + "promotionEvents.promotionalDates.startDate.Day": -1 + }, + output: { + eventName: "$promotionEvents.eventName", + startDate: "$promotionEvents.promotionalDates.startDate" + } + } + } + } + } +]) +``` + +The first two results returned by this query are: + +```json +[ + { + "_id": "4a99546f-a1d2-4e61-ae9f-b8c7c1faf73c'", + "storeName": "Lakeshore Retail | Stationery Nook - West Van", + "top2RecentPromotions": [ + { + "eventName": "Crazy Markdown Madness", + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + } + }, + { + "eventName": "Flash Sale Fiesta", + "startDate": { + "Year": 2024, + "Month": 6, + "Day": 23 + } + } + ] + }, + { + "_id": "e0c47a06-4fe0-46b7-a309-8971bbb3978f", + "storeName": "VanArsdel, Ltd. | Baby Products Bargains - Elainamouth", + "top2RecentPromotions": [ + { + "eventName": "Crazy Deal Days", + "startDate": { + "Year": 2024, + "Month": 9, + "Day": 21 + } + } + ] + } +] +```