diff --git a/api-reference/operators/aggregation/$count.md b/api-reference/operators/aggregation/$count.md new file mode 100644 index 0000000..ce44ad2 --- /dev/null +++ b/api-reference/operators/aggregation/$count.md @@ -0,0 +1,102 @@ +--- +title: $count +description: The $count stage returns a count of the number of documents at this stage of the aggregation pipeline. +type: operators +category: aggregation +--- + +# $count + +The `$count` stage passes a document to the next stage that contains a count of the number of documents input to the stage. This is useful for getting the total number of documents that match earlier pipeline stages. + +## Syntax + +```javascript +{ + $count: +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`string`** | Required. The name of the output field which has the count as its value. Must be a non-empty string, must not start with `$`, and must not contain the `.` character. | + +## Examples + +Consider this sample document from the stores collection. + +```json +{ + "_id": "2cf3f885-9962-4b67-a172-aa9039e9ae2f", + "name": "First Up Consultants | Bed and Bath Center - South Amir", + "location": { + "lat": 60.7954, + "lon": -142.0012 + }, + "staff": { + "totalStaff": { + "fullTime": 18, + "partTime": 17 + } + }, + "sales": { + "totalSales": 37701 + } +} +``` + +### Example 1: Count all documents + +Count the total number of documents in the collection: + +```javascript +db.stores.aggregate([ + { $count: "totalStores" } +]) +``` + +This query returns: + +```json +[ + { "totalStores": 5 } +] +``` + +### Example 2: Count documents after filtering + +Count stores that have more than 10 full-time staff: + +```javascript +db.stores.aggregate([ + { $match: { "staff.totalStaff.fullTime": { $gt: 10 } } }, + { $count: "highStaffStores" } +]) +``` + +This query returns: + +```json +[ + { "highStaffStores": 3 } +] +``` + +### Example 3: Count with $unwind + +Count the total number of promotion events across all stores: + +```javascript +db.stores.aggregate([ + { $unwind: "$promotionEvents" }, + { $count: "totalPromotionEvents" } +]) +``` + +## Key Takeaways + +- **Single output document** — `$count` always returns exactly one document with a single field +- **Close to, but not the same as, `$group`** — `{ $count: "total" }` resembles `{ $group: { _id: null, total: { $sum: 1 } } }` followed by `{ $project: { _id: 0 } }`, and the two agree whenever any document reaches the stage. They diverge on empty input: `$count` builds an ungrouped aggregate, which always produces a row, so it returns `{ "total": 0 }`, while `$group` performs a real grouping and returns nothing at all. Use `$count` when a downstream stage depends on always receiving a document. +- **Field name restrictions** — the output field name must be non-empty, cannot start with `$`, and cannot contain `.` diff --git a/api-reference/operators/aggregation/$currentop.md b/api-reference/operators/aggregation/$currentop.md new file mode 100644 index 0000000..46bc49b --- /dev/null +++ b/api-reference/operators/aggregation/$currentop.md @@ -0,0 +1,77 @@ +--- +title: $currentOp +description: The $currentOp stage returns information on active and queued operations for the database. +type: operators +category: aggregation +--- + +# $currentOp + +The `$currentOp` stage returns a stream of documents containing information on active and queued operations for the database instance. This stage must be the first stage in the pipeline and is run on the `admin` database. + +## Syntax + +```javascript +db.adminCommand({ + aggregate: 1, + pipeline: [ + { + $currentOp: { + allUsers: , + idleConnections: , + idleCursors: , + idleSessions: , + localOps: + } + } + ], + cursor: {} +}) +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`allUsers`** | Optional. Boolean. If `true`, reports operations for all users. Default: `false`. | +| **`idleConnections`** | Optional. Boolean. If `true`, reports on idle connections. Default: `false`. | +| **`idleCursors`** | Optional. Boolean. If `true`, reports on idle cursors. Default: `false`. | +| **`idleSessions`** | Optional. Boolean. If `true`, reports on idle sessions. Default: `false`. | +| **`localOps`** | Optional. Boolean. If `true`, reports operations running locally on the current instance. Default: `false`. | + +## Examples + +### Example 1: List active operations + +Return all currently active operations: + +```javascript +db.adminCommand({ + aggregate: 1, + pipeline: [ + { $currentOp: { allUsers: true } } + ], + cursor: {} +}) +``` + +### Example 2: Filter active operations + +Return active operations for a specific database, combined with `$match`: + +```javascript +db.adminCommand({ + aggregate: 1, + pipeline: [ + { $currentOp: { allUsers: true } }, + { $match: { "ns": /^mydb\./ } } + ], + cursor: {} +}) +``` + +## Key Takeaways + +- **Must be first stage** — `$currentOp` must be the first stage in the aggregation pipeline +- **Admin database only** — this stage must be run against the `admin` database using `db.adminCommand()` +- **Collection-agnostic** — does not operate on a specific collection diff --git a/api-reference/operators/aggregation/$replaceroot.md b/api-reference/operators/aggregation/$replaceroot.md new file mode 100644 index 0000000..dc758b2 --- /dev/null +++ b/api-reference/operators/aggregation/$replaceroot.md @@ -0,0 +1,136 @@ +--- +title: $replaceRoot +description: The $replaceRoot stage replaces the input document with the specified document. +type: operators +category: aggregation +--- + +# $replaceRoot + +The `$replaceRoot` stage replaces the input document with the specified document. The operation replaces all existing fields in the input document, including the `_id` field. This is useful for promoting an embedded document to the top level. + +## Syntax + +```javascript +{ + $replaceRoot: { + newRoot: + } +} +``` + +## Parameters + +| Parameter | Description | +| --- | --- | +| **`newRoot`** | Required. A document expression that resolves to a document. The expression can be any valid expression that resolves to a document, such as a field path to an embedded document, a `$mergeObjects` expression, or a literal document. | + +## 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 } + ] + } +} +``` + +### Example 1: Promote an embedded document + +Promote the `staff.totalStaff` subdocument to the top level: + +```javascript +db.stores.aggregate([ + { $replaceRoot: { newRoot: "$staff.totalStaff" } }, + { $limit: 2 } +]) +``` + +This query returns: + +```json +[ + { "fullTime": 8, "partTime": 20 } +] +``` + +### Example 2: Use $mergeObjects to combine fields + +Merge the staff subdocument with additional top-level fields: + +```javascript +db.stores.aggregate([ + { + $replaceRoot: { + newRoot: { + $mergeObjects: [ + "$staff.totalStaff", + { storeName: "$name", totalSales: "$sales.totalSales" } + ] + } + } + }, + { $limit: 2 } +]) +``` + +This query returns: + +```json +[ + { + "fullTime": 8, + "partTime": 20, + "storeName": "First Up Consultants | Beverage Shop - Satterfieldmouth", + "totalSales": 75670 + } +] +``` + +### Example 3: Replace root after $unwind + +Extract individual sales categories as top-level documents: + +```javascript +db.stores.aggregate([ + { $unwind: "$sales.salesByCategory" }, + { + $replaceRoot: { + newRoot: { + $mergeObjects: [ + "$sales.salesByCategory", + { storeName: "$name" } + ] + } + } + }, + { $limit: 3 } +]) +``` + +## Limitations + +- If `newRoot` evaluates to a missing value or a non-document type, the operation errors + +## Key Takeaways + +- **Replaces the entire document** — the output document is the evaluated `newRoot` expression +- **`$replaceWith` is an alias** — `{ $replaceWith: }` is shorthand for `{ $replaceRoot: { newRoot: } }` +- **Combine with `$mergeObjects`** — use `$mergeObjects` to preserve fields from the original document while promoting an embedded document diff --git a/api-reference/operators/aggregation/$search.md b/api-reference/operators/aggregation/$search.md new file mode 100644 index 0000000..51fbe3b --- /dev/null +++ b/api-reference/operators/aggregation/$search.md @@ -0,0 +1,130 @@ +--- +title: $search +description: The $search stage in the aggregation pipeline runs a vector similarity search through the cosmosSearch or knnBeta operator. +type: operators +category: aggregation +--- + +# $search + +The `$search` stage in the aggregation pipeline runs a vector similarity search over a vector index. It carries exactly one search operator — `cosmosSearch`, or the deprecated `knnBeta` — and returns the documents whose stored embedding is closest to a query vector. + +`$search` must be the first stage in the pipeline, and the field named by `path` must be covered by a vector index. + +> `$search` in DocumentDB is a vector search stage. It does not accept text-search operators: a spec such as `{ $search: { text: { ... } } }` is rejected with `Unrecognized $search option: text`. For full-text queries, use the `$text` query operator against a text index. For new work, prefer [`$vectorSearch`](./%24vectorsearch.md), which is the current stage for vector search and takes a clearer spec; `$search` remains for compatibility with existing `cosmosSearch` and `knnBeta` queries. + +## Syntax + +```javascript +{ + $search: { + index: , + cosmosSearch: { + path: , + vector: [, ...], + k: , + filter: , + exact: , + oversampling: + } + } +} +``` + +## Parameters + +The stage takes exactly one search operator, plus a small number of options alongside it. + +| Parameter | Description | +| --- | --- | +| **`cosmosSearch`** | The search operator, holding the query spec described below. Exactly one operator must be present — supplying both `cosmosSearch` and `knnBeta` fails with `The $search spec can only contain one search operator.`, and supplying neither fails with `Invalid search spec provided, must include one of the supported operators.` | +| **`knnBeta`** | Deprecated alias kept for backward compatibility. It takes the same spec as `cosmosSearch`, except that `filter` and `score` are rejected outright. Use `cosmosSearch` instead. | +| **`index`** | Optional. The name of the index to search, as a string. | +| **`returnStoredSource`** | Optional. Accepted for compatibility and ignored. | +| **`count`** | Optional. Parsed and validated, but the resulting count metadata is **not yet emitted in the results**, so the option currently has no observable effect. | + +Any other key alongside the operator is rejected with `Unrecognized $search option: `. + +### Operator spec + +| Field | Description | +| --- | --- | +| **`path`** | Required. The document field holding the stored embedding. Must be covered by a vector index. Omitting it fails with `$path is required field for using a vector index.` | +| **`vector`** | Required. The query embedding, as a non-empty array of numbers. Omitting it fails with `$vector is required field for using a vector index.` | +| **`k`** | Required. The number of documents to return, as a positive integer. | +| **`filter`** | Optional. A query document intersected with the vector search. Requires vector pre-filtering to be enabled on the server; when it is not, the query fails with `$filter is not supported for vector search yet.` Not supported at all with `knnBeta`. | +| **`exact`** | Optional. Boolean. Runs an exact search instead of an approximate one. | +| **`oversampling`** | Optional. Widens the candidate set considered during an approximate search, improving recall at the cost of latency. | +| **`score`** | Optional. Not supported with `knnBeta`, which rejects it with `$score is not supported for knnBeta queries.` | + +## Examples + +The examples on this page use the following documents in a `products` collection, with a vector index on `embedding`. + +```json +[ + { "_id": 1, "name": "Espresso Machine", "category": "appliance", "embedding": [0.9, 0.1, 0.05] }, + { "_id": 2, "name": "Coffee Grinder", "category": "appliance", "embedding": [0.85, 0.15, 0.1] }, + { "_id": 3, "name": "Merlot Bottle", "category": "wine", "embedding": [0.05, 0.9, 0.2] }, + { "_id": 4, "name": "Chardonnay Bottle", "category": "wine", "embedding": [0.1, 0.85, 0.25] } +] +``` + +### Example 1: Nearest neighbors for a query vector + +Return the three documents closest to a query embedding: + +```javascript +db.products.aggregate([ + { + $search: { + cosmosSearch: { + path: "embedding", + vector: [0.88, 0.12, 0.07], + k: 3 + } + } + }, + { $project: { name: 1, category: 1 } } +]) +``` + +```json +[ + { "_id": 1, "name": "Espresso Machine", "category": "appliance" }, + { "_id": 2, "name": "Coffee Grinder", "category": "appliance" }, + { "_id": 4, "name": "Chardonnay Bottle", "category": "wine" } +] +``` + +### Example 2: Exact search + +Set `exact` to `true` to compare against every indexed vector rather than an approximate candidate set. This is slower, and useful when you need a reference result to measure recall against: + +```javascript +db.products.aggregate([ + { + $search: { + cosmosSearch: { + path: "embedding", + vector: [0.88, 0.12, 0.07], + k: 3, + exact: true + } + } + }, + { $project: { name: 1 } } +]) +``` + +## Behavior + +- **`$search` must come first.** Placing it anywhere else fails with `$search must appear as the initial stage in the pipeline sequence.` The same applies when the pipeline already carries a limit ahead of it. +- **One operator per spec.** The stage rejects a spec carrying more than one search operator, and a spec carrying none. +- **`path` must be indexed.** The field named by `path` must be covered by a vector index; see [`$vectorSearch`](./%24vectorsearch.md) for creating one. + +## Related content + +- [`$vectorSearch`](./%24vectorsearch.md) — the current vector search stage, and the one to prefer for new queries. +- [`$project`](./%24project.md) — shape the documents returned by the search. +- [`$limit`](./%24limit.md) — narrow the result set further; `k` already bounds it. diff --git a/api-reference/operators/aggregation/$setwindowfields.md b/api-reference/operators/aggregation/$setwindowfields.md new file mode 100644 index 0000000..20fb413 --- /dev/null +++ b/api-reference/operators/aggregation/$setwindowfields.md @@ -0,0 +1,197 @@ +--- +title: $setWindowFields +description: The $setWindowFields stage performs operations on a specified span of documents (a window) and returns results based on the chosen window operator. +type: operators +category: aggregation +--- + +# $setWindowFields + +The `$setWindowFields` stage groups documents into partitions, applies window functions over a defined span of documents within each partition, and outputs a new field with the result for each document. This is useful for running calculations (like running averages, ranks, and cumulative sums) without collapsing documents into groups. + +## Syntax + +```javascript +{ + $setWindowFields: { + partitionBy: , + sortBy: { + : <1 or -1>, + ... + }, + output: { + : { + : , + window: { + // a document window: + documents: [, ] + + // -- or a range window, mutually exclusive with the above: + // range: [, ], + // unit: