> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  drivers: shell, nodejs
-->

# $queryStats (aggregation stage)

## Definition

**Warning:**

The `$queryStats` aggregation stage is unsupported and is not guaranteed to be stable in a future release. Don't build functionality that relies on a specific output format of this stage, since the output may change in a future release.

Returns runtime statistics for recorded queries.

`$queryStats` collects and reports metrics for [`aggregate()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.aggregate.md#mongodb-method-db.collection.aggregate), [`find()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.find.md#mongodb-method-db.collection.find), [`distinct()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.distinct.md#mongodb-method-db.collection.distinct), [`count()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.count.md#mongodb-method-db.collection.count), [`update()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.update.md#mongodb-method-db.collection.update), [`insert()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.insert.md#mongodb-method-db.collection.insert), [`deleteOne()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.deleteone.md#mongodb-method-db.collection.deleteOne), and [`deleteMany()`](https://www.mongodb.com/docs/manual/reference/method/db.collection.deletemany.md#mongodb-method-db.collection.deleteMany) queries. `$queryStats` does not collect information for queries that use [Queryable Encryption.](https://www.mongodb.com/docs/manual/core/queryable-encryption.md#std-label-qe-manual-feature-qe)

## Requirements

The `$queryStats` stage is enabled on deployments hosted on [MongoDB Atlas](https://www.mongodb.com/docs/atlas/) with a cluster tier of at least M10.

To run the `$queryStats` stage, your pipeline must meet the following requirements:

- The pipeline must be run on the `admin` database.

- `$queryStats` must be the first stage in the pipeline.

## Syntax

```javascript
db.adminCommand( {
   aggregate: 1,
   pipeline: [
      {
         $queryStats: {
            transformIdentifiers: {
               algorithm: <string>,
               hmacKey: <binData> /* subtype 8 - used for sensitive data */
            }
         }
      }
   ],
   cursor: { }
 } )
```

**Important:**

You cannot run `$queryStats` on a specific collection. For complete examples, see [Examples.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-examples)

### Command Fields

`$queryStats` takes the following fields:

| Field | Necessity | Type | Description |
| --- | --- | --- | --- |
| `transformIdentifiers` | Optional | Document | Specifies additional transformation options for the `$queryStats` output. |
| `transformIdentifiers``.algorithm` | Required if specifying the `transformIdentifiers` object | String | The type of hash transformation applied to namespace information and field names in output. The only currently supported `algorithm` value is `hmac-sha-256`. |
| `transformIdentifiers``.hmacKey` | Required if specifying the `transformIdentifiers` object | binData | The private key input in the HMAC transformation. |

## Access Control

If your deployment enforces access control, the user running `$queryStats` must have the following permissions:

- To run `$queryStats` without the `transformIdentifiers` option, the user must have the [`queryStatsRead`](https://www.mongodb.com/docs/manual/reference/privilege-actions.md#mongodb-authaction-queryStatsRead) privilege action.

- To run `$queryStats` with the `transformIdentifiers` option, the user must have the both the [`queryStatsRead`](https://www.mongodb.com/docs/manual/reference/privilege-actions.md#mongodb-authaction-queryStatsRead) and [`queryStatsReadTransformed`](https://www.mongodb.com/docs/manual/reference/privilege-actions.md#mongodb-authaction-queryStatsReadTransformed) privilege actions.

The built-in [`clusterMonitor`](https://www.mongodb.com/docs/manual/reference/built-in-roles.md#mongodb-authrole-clusterMonitor) role provides the `queryStatsRead` and `queryStatsReadTransformed` privileges. The following example grants the `clusterMonitor` role on the `admin` database:

```javascript
db.grantRolesToUser(
   "<user>",
   [ { role: "clusterMonitor", db: "admin" } ]
)
```

## Behavior

The following sections describe behavioral details of the `$queryStats` stage.

### How $queryStats Tracks Query Statistics

Statistics for the `$queryStats` stage are tracked in a virtual collection that is stored in-memory. The memory limit for the virtual collection is 1% of the system's total memory.

### How $queryStats Samples Operations

**New in version 9.0**

Starting in MongoDB 9.0, `$queryStats` collects stats for a sample of 1% of read and write operations by default. To change the sampling rate, set the [`internalQueryStatsSampleRate`](https://www.mongodb.com/docs/manual/reference/parameters.md#mongodb-parameter-param.internalQueryStatsSampleRate) parameter for read operations or the [`internalQueryStatsWriteCmdSampleRate`](https://www.mongodb.com/docs/manual/reference/parameters.md#mongodb-parameter-param.internalQueryStatsWriteCmdSampleRate) parameter for write operations. Both parameters accept a value between `0.0` and `1.0`.

Because `$queryStats` reports only the operations that MongoDB samples, its output represents a subset of the operations run against your deployment. Counts and execution times reflect only the sampled operations.

### How $queryStats Groups Returned Documents

`$queryStats` groups queries with common properties into the same output document. The resulting document is called a **query stats
entry**.

`$queryStats` groups similar queries together by normalizing user-provided field values to their data types. For example, a filter specified as `{ item: 'card' }` is normalized to `{ item :
'?string'}`. `$queryStats` also normalizes the values of some query options like `hint` and `comment`.

`$queryStats` preserves literal values for options like `readConcern` and `readPreference`.

For the complete list of options included in a query stats entry, see [find Command Query Shape.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-find-query-shape)

### How $queryStats Transforms Data Using transformIdentifiers

When an HMAC key is specified to the `transformIdentifiers` option, `$queryStats` uses the HMAC key to apply an HMAC-SHA-256 hash function on the following data:

- Document field names

- Collection names

- Database names

`$queryStats` **does not** apply the HMAC transformation to the following data:

- MQL keywords such as operator names (for example, `$gte`).

- Parameter names such as the `partitionBy` parameter in [`$setWindowFields`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields)

- Field values. `$queryStats` normalizes field values in a query to their data types (such as number or string) when the query is recorded. `$queryStats` never stores field values that contain user data.

For an example of transformed output, see [Transformed Example.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-example-transformed)

### $queryStats Log Entries

MongoDB records `$queryStats` operations in the [deployment logs](https://www.mongodb.com/docs/atlas/mongodb-logs/). By default, MongoDB only logs the invocation of `$queryStats` operations, not the operation's output. For `$queryStats` operations that include the `transformIdentifiers` option, you can specify whether the transformed output is included in the log entry.

To learn how to control `$queryStats` logging behavior, see [Toggle $queryStats Log Output.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats/toggle-logging.md#std-label-queryStats-toggle-logging)

### Change Streams

Query stats for [change streams](https://www.mongodb.com/docs/manual/changestreams.md#std-label-changeStreams) are updated when one of these events occur:

- A cursor is created

- A [`getMore`](https://www.mongodb.com/docs/manual/reference/command/getmore.md#mongodb-dbcommand-dbcmd.getMore) operation completes

- A cursor closes

Query stats reported for change streams have these behaviors:

- Execution metrics such as `totalExecMicros` contain information for the most recent operation (cursor creation, `getMore`, or cursor close).

- Internal `getMore` operations increment the `execCount` metric.

- `firstResponseExecMicros` and `totalExecMicros` are always the same because stats are collected and updated for each `getMore` operation.

- When the cursor closes, `lastExecutionMicros` is 0.

### Sharded Cluster Behavior

**New in version 8.3**

In sharded clusters, MongoDB records query statistics separately on each `mongod` and `mongos` when `$queryStats` is enabled. Shard servers also record statistics for queries that originate from `mongos`. These provide more complete shard-level metrics for queries that users route through `mongos`.

## Output

`$queryStats` returns an array of query stats entries. Some query stats entry properties contain literal values, and some properties are normalized to group common queries.

**Note:**

MongoDB 9.0 updates the `$queryStats` output structure to improve metrics organization.

Query stats entries contain the following top-level documents:

| Document | Description |
| --- | --- |
| `key` | The unique combination of attributes that define an entry in the query stats output. The `key` contains attributes such as: [Query shape](https://www.mongodb.com/docs/manual/core/query-shapes.md#std-label-query-shapes); Client information; Read concern; [Collection type](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-collectionType) Each unique combination of attributes creates a separate entry in the `$queryStats` virtual collection. |
| `asOf` | The UTC time when `$queryStats` read this entry from the `$queryStats` virtual collection. `asOf` does not necessarily return the same UTC time for each result. Internally, the data structure is partitioned, and each partition will be read at an individual point in time. |
| `metrics` | Contains aggregated runtime metrics associated with each query stats entry. Each query stats entry records statistics for each query that shares the same key. |

Each document in the output array contains the following fields:

| Field | Type | Literal or Normalized | Description |
| --- | --- | --- | --- |
| `key` | Document | Literal | Contains the query shape and additional query attributes that group a set of queries together |
| `key.queryShape` | Document | Literal | Contains attributes used to group similar queries together. For more information, see [Query Shape.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-queryShape) |
| `key.client` | Document | Literal | Describes client information associated with the key |
| `key.client.application` | Document | Literal | The client application name |
| `key.client.driver` | Document | Literal | Describes the driver used to issue the query |
| `key.client.driver.name` | String | Literal | Name of the driver used to issue the query. Possible values include `mongosh` and `nodejs`. |
| `key.client.driver.version` | String | Literal | Version number of the driver used to issue the query |
| `key.client.os` | Document | Literal | Describes the operating system used by the client that issued the query |
| `key.client.os.type` | String | Literal | Type of the operating system |
| `key.client.os.name` | String | Literal | Name of the operating system |
| `key.client.os.architecture` | String | Literal | Architecture of the operating system. Possible values include `arm64` and `x86_64`. |
| `key.client.os.version` | String | Literal | Version number of the operating system |
| `key.readConcern` | Document | Literal | The [read concern](https://www.mongodb.com/docs/manual/reference/read-concern.md#std-label-read-concern) for the key |
| `key.collectionType` | String | Literal | The type of collection the query was issued on. For more information, see [Collection Type.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-collectionType) |
| `key.hint` | Document or String | Normalized | The index that was used as a [hint](https://www.mongodb.com/docs/manual/reference/method/cursor.hint.md#std-label-cursor-hint) for the query |
| `key.batchSize` | String | Normalized | The [batch size](https://www.mongodb.com/docs/manual/reference/method/cursor.batchsize.md#std-label-cursor-batchSize) for the key. Batch size specifies the maximum number of documents that can be returned in each batch of a query result. By default, the initial batch size is the lesser of `101` documents or 16 mebibytes (MiB) worth of documents. Subsequent batches have a maximum size of 16 MiB. `batchSize` can enforce a smaller limit than 16 MiB, but not a larger one. When set, the `batchSize` is the lesser of `batchSize` documents or 16 MiB worth of documents. |
| `key.comment` | String | Normalized | Comment associated with the key |
| `key.maxTimeMS` | String | Normalized | [maxTimeMS](https://www.mongodb.com/docs/manual/reference/method/cursor.maxtimems.md#std-label-cursor-maxTimeMS) value associated with the key |
| `key.noCursorTimeout` | Boolean | Normalized | [noCursorTimeout](https://www.mongodb.com/docs/manual/reference/method/cursor.nocursortimeout.md#std-label-cursor-noCursorTimeout) option associated with the key |
| `key.readPreference` | String | Literal | [Read preference](https://www.mongodb.com/docs/manual/core/read-preference.md#std-label-read-preference) associated with the key |
| `key.apiVersion` | String | Literal | The Stable API version associated with the key. See [MongoDB Stable API for Server Upgrades.](https://www.mongodb.com/docs/manual/reference/stable-api.md#std-label-stable-api) |
| `key.apiStrict` | Boolean | Literal | The `apiStrict` parameter value associated with the key. See [Stable API Parameters.](https://www.mongodb.com/docs/manual/reference/stable-api.md#std-label-stable-api-params) |
| `key.apiDeprecationErrors` | Boolean | Literal | The `apiDeprecationErrors` parameter value associated with the key. See [Stable API Parameters.](https://www.mongodb.com/docs/manual/reference/stable-api.md#std-label-stable-api-params) |
| `keyHash` | String | Literal | A hashed representation of the values in the `key`. Each unique `keyHash` value corresponds to a unique entry in the `$queryStats` memory store. |
| `queryShapeHash` | String | Literal | **New in version 8.0** `queryShapeHash` is a hexadecimal string with the hash of a [query shape](https://www.mongodb.com/docs/manual/reference/glossary.md#std-term-query-shape). For details, see [Query Shapes.](https://www.mongodb.com/docs/manual/core/query-shapes.md#std-label-query-shapes) |
| `metrics` | Document | Literal | Describes runtime statistics for the key |
| `metrics.cursor` | Document | Literal | **New in version 9.0** Metrics related to the cursor and batching protocol |
| `metrics``.cursor``.firstResponseExecMicros` | Document | Literal | **Changed in version 9.0** Describes the time spent from when a query within the key began processing to when the server returns the first batch of results All subfields of `firstResponseExecMicros` are reported in microseconds. |
| `metrics.queryExec` | Document | Literal | **New in version 9.0** Metrics related to query execution |
| `metrics``.queryExec``.docsReturned` | Document | Literal | **Changed in version 9.0** Describes the number of documents returned by queries within the key |
| `metrics``.queryExec``.docsReturned``.sum` | NumberLong | Literal | Total number of documents returned by queries with the given key |
| `metrics``.queryExec``.docsReturned``.max` | NumberLong | Literal | Maximum number of documents returned by a query with the given key |
| `metrics``.queryExec``.docsReturned``.min` | NumberLong | Literal | Fewest number of documents returned by a query with the given key |
| `metrics``.queryExec``.docsReturned``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of number of documents returned by a query within the key. A high `sumOfSquares` value indicates high variance in the number of documents returned between individual queries. |
| `metrics``.queryExec``.keysExamined` | Document | Literal | Describes the number of keys examined by queries |
| `metrics``.queryExec``.keysExamined``.sum` | Integer | Literal | Total number of keys examined |
| `metrics``.queryExec``.keysExamined``.max` | NumberLong | Literal | Maximum number of keys examined |
| `metrics``.queryExec``.keysExamined``.min` | NumberLong | Literal | Fewest number of keys examined |
| `metrics``.queryExec``.keysExamined``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of number of keys examined. A high `sumOfSquares` value indicates high variance in the number of keys examined in individual queries. |
| `metrics``.queryExec``.docsExamined` | Document | Literal | **Changed in version 9.0** Describes the number of documents examined by queries |
| `metrics``.queryExec``.docsExamined``.sum` | Integer | Literal | Total number of documents examined in the query |
| `metrics``.queryExec``.docsExamined``.max` | NumberLong | Literal | Maximum number of documents examined |
| `metrics``.queryExec``.docsExamined``.min` | NumberLong | Literal | Minimum number of documents examined |
| `metrics``.queryExec``.docsExamined``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of number of documents examined. A high `sumOfSquares` value indicates high variance in the number of documents examined in individual queries. |
| `metrics``.queryExec``.bytesRead` | Document | Literal | **Changed in version 9.0** Describes the number of bytes read by queries |
| `metrics``.queryExec``.bytesRead``.sum` | Integer | Literal | Total number of bytes read in the query |
| `metrics``.queryExec``.bytesRead``.max` | NumberLong | Literal | Maximum number of bytes read |
| `metrics``.queryExec``.bytesRead``.min` | NumberLong | Literal | Minimum number of bytes read |
| `metrics``.queryExec``.bytesRead``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of number of bytes read |
| `metrics``.queryExec``.readTimeMicros` | Document | Literal | **Changed in version 9.0** Describes the read time of the query in microseconds |
| `metrics``.queryExec``.readTimeMicros``.sum` | Integer | Literal | Total read time of the query in microseconds |
| `metrics``.queryExec``.readTimeMicros``.max` | NumberLong | Literal | Maximum read time of the query in microseconds |
| `metrics``.queryExec``.readTimeMicros``.min` | NumberLong | Literal | Minimum read time of the query in microseconds |
| `metrics``.queryExec``.readTimeMicros``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of read time of the query in microseconds |
| `metrics``.queryExec``.delinquentAcquisitions` | NumberLong | Literal | **Changed in version 9.0** Number of times that query operations exceeded the expected execution ticket acquisition time. |
| `metrics``.queryExec``.totalAcquisitionDelinquencyMillis` | NumberLong | Literal | **Changed in version 9.0** Total time in milliseconds that query operations exceeded the expected execution ticket acquisition time. |
| `metrics``.queryExec``.maxAcquisitionDelinquencyMillis` | NumberLong | Literal | **Changed in version 9.0** Longest duration of time in milliseconds that a query operation exceeded the expected execution ticket acquisition time. |
| `metrics.lastExecutionMicros` | NumberLong | Literal | Execution runtime for the most recent query for all queries with the given key |
| `metrics.execCount` | NumberLong | Literal | Number of times that queries with the given key have been executed |
| `metrics.queryPlanner` | Document | Literal | **Changed in version 9.0** Metrics related to query plans |
| `metrics``.queryPlanner``.hasSortStage` | Document | Literal | **Changed in version 9.0** Object that contains two fields: `true` and `false`. Each field counts the number of matching queries where the value of `hasSortStage` is `true` or `false`, respectively. `hasSortStage` is `true` when MongoDB must sort the documents after it receives the documents from a cursor. |
| `metrics``.queryPlanner``.usedDisk` | Document | Literal | **Changed in version 9.0** Object that contains two fields: `true` and `false`. Each field counts the number of matching queries where the value of `usedDisk` is `true` or `false`, respectively. `usedDisk` is `true` when the query writes data to temporary files due to memory restrictions. |
| `metrics``.queryPlanner``fromMultiPlanner` | Document | Literal | **Changed in version 9.0** Object that contains two fields: `true` and `false`. Each field counts the number of matching queries where the value of `fromMultiPlanner` is `true` or `false`, respectively. `fromMultiPlanner` is `true` when the query planner evaluates multiple plans before choosing the winning execution plan for the query. |
| `metrics``.queryPlanner``fromPlanCache` | Document | Literal | **Changed in version 9.0** Object that contains two fields: `true` and `false`. Each field counts the number of matching queries where the value of `fromPlanCache` is `true` or `false`, respectively. `fromPlanCache` is `true` when the query planner is able to use a plan from the plan cache. |
| `metrics``.queryPlanner``.planShapeCounters` | Document | Literal | **New in version 9.0** Counts of the plan shapes that MongoDB selected for queries with the given key. For details, see [Plan Shape Counters.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-planShapeCounters) |
| `metrics``.queryPlanner``.planShapeCounters``.patterns` | Document | Literal | **New in version 9.0** Counts of the overall shapes of the winning plans. Each winning plan matches at most one pattern. |
| `metrics``.queryPlanner``.planShapeCounters``.nodes` | Document | Literal | **New in version 9.0** Counts of the types of plan stages that appear in the winning plans. A single winning plan can match multiple node counters. |
| `metrics``.queryPlanner``.planShapeCounters``.accessPaths` | Document | Literal | **New in version 9.0** Counts of the data access paths and index bounds that the winning plans use. A single winning plan can match multiple access path counters. |
| `metrics.writes` | Document | Literal | **Changed in version 9.0** Metrics related to writes |
| `metrics``.writes``nMatched` | NumberLong | Literal | **New in version 9.0** The number of documents that an update selects |
| `metrics``.writes``nUpserted` | NumberLong | Literal | **New in version 9.0** The number of documents that an update operation inserts |
| `metrics``.writes``nModified` | NumberLong | Literal | **New in version 9.0** The number of documents that an update operation modifies |
| `metrics``.writes``nDeleted` | NumberLong | Literal | **New in version 9.0** The number of documents that a delete operation deletes |
| `metrics``.writes``nInserted` | NumberLong | Literal | **New in version 9.0** The number of documents that an insert operation inserts, excluding upserts |
| `metrics``.writes``nUpdateOps` | NumberLong | Literal | **New in version 9.0** The number of updates in the original update request |
| `metrics.totalExecMicros` | Document | Literal | Describes the total time spent running queries with the given key. If the query resulted in [`getMores`](https://www.mongodb.com/docs/manual/reference/command/getmore.md#mongodb-dbcommand-dbcmd.getMore), `totalExecMicros` includes the time spent processing the `getMore` requests. `totalExecMicros` does not include time spent waiting for the client. All subfields of `totalExecMicros` are reported in microseconds. |
| `metrics``.totalExecMicros``.sum` | NumberLong | Literal | Total time spent running queries with the given key |
| `metrics``.totalExecMicros``.max` | NumberLong | Literal | Longest amount of time spent running a query with the given key |
| `metrics``.totalExecMicros``.min` | NumberLong | Literal | Shortest amount of time spent running a query with the given key |
| `metrics``.totalExecMicros``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of the total execution times for all queries with the given key. A high `sumOfSquares` value indicates high variance in query execution times. |
| `metrics``.cursor``.firstResponseExecMicros``.sum` | NumberLong | Literal | Combined amount of time spent from the beginning of query processing to when the server returns the first batch of results |
| `metrics``.cursor``.firstResponseExecMicros``.max` | NumberLong | Literal | Longest amount of time spent from the beginning of query processing to when the server returns the first batch of results |
| `metrics``.cursor``.firstResponseExecMicros``.min` | NumberLong | Literal | Shortest amount of time spent from the beginning of query processing to when the server returns the first batch of results |
| `metrics``.cursor``.firstResponseExecMicros``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of amounts of time spent from the beginning of query processing to when the server returns the first batch of results. A high `sumOfSquares` value indicates high variance in query processing times. |
| `metrics.firstSeenTimestamp` | Date | Literal | Time that a query with the given key was first used since the last restart |
| `metrics.latestSeenTimestamp` | Date | Literal | Time that a query with the given key was most recently used |
| `metrics.workingTimeMillis` | NumberLong | Literal | The operation execution time, excluding intentional pauses such as time waiting on locks and flow control. |
| `metrics``.costBasedRanker` | Document | Literal | Contains metrics related to CBR (Cost-Based Ranking) when it is used during query planning. CBR evaluates multiple query plans and selects the most efficient plan based on estimated costs. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.nDocsSampled` | Document | Literal | Contains metrics related to the number of documents sampled during cost-based ranking for queries with the given key. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.nDocsSampled``.sum` | NumberLong | Literal | Total number of documents sampled during cost-based ranking. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.nDocsSampled``.max` | NumberLong | Literal | Maximum number of documents sampled during cost-based ranking. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.nDocsSampled``.min` | NumberLong | Literal | Minimum number of documents sampled during cost-based ranking. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.nDocsSampled``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of the number of documents sampled during cost-based ranking. A high `sumOfSquares` value indicates high variance in the number of documents sampled for individual queries. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods` | Document | Literal | Contains counts for each cardinality estimation method used during cost-based ranking. Each field represents the number of times a particular estimation method was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Histogram` | NumberLong | Literal | Number of times histogram-based cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Sampling` | NumberLong | Literal | Number of times sampling-based cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Heuristics` | NumberLong | Literal | Number of times heuristic-based cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Mixed` | NumberLong | Literal | Number of times a mixed approach to cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Metadata` | NumberLong | Literal | Number of times metadata-based cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.costBasedRanker``.cardinalityEstimationMethods``.Code` | NumberLong | Literal | Number of times code-based cardinality estimation was used. **New in version 8.3.3** |
| `metrics``.cpuNanos` | Document | Literal | Contains metrics related to CPU usage for a query operation. This document is only available on Linux systems. **New in version 8.2** |
| `metrics``.cpuNanos``.sum` | NumberLong | Literal | Total CPU time spent by a query operation in nanoseconds. This field is only available on Linux systems. **New in version 8.2** |
| `metrics``.cpuNanos``.max` | NumberLong | Literal | Maximum CPU time spent on a query operation in nanoseconds. This field is only available on Linux systems. **New in version 8.2** |
| `metrics``.cpuNanos``.min` | NumberLong | Literal | Minimum CPU time spent on a query operation in nanoseconds. This field is only available on Linux systems. **New in version 8.2** |
| `metrics``.cpuNanos``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of CPU time spent on query operations. This field is only available on Linux systems. A high `sumOfSquares` value indicates high variance in the CPU time for individual queries. **New in version 8.2** |
| `metrics``.clusterPeakTrackedMemBytes` | NumberLong | Literal | Sum of local peak tracked memory and sum of peak tracked memory from all remote shards contacted during query execution. **New in version 9.0** |
| `metrics``.peakTrackedMemBytes` | NumberLong | Literal | Peak local tracked memory usage. **New in version 9.0** |
| `metrics``.planningTimeMicros` | Document | Literal | Contains metrics related to the time spent during query planning for queries with the given key. All `planningTimeMicros` subfields are reported in microseconds. **New in version 8.3** |
| `metrics``.planningTimeMicros``.sum` | NumberLong | Literal | Total query planning time. **New in version 8.3** |
| `metrics``.planningTimeMicros``.max` | NumberLong | Literal | Maximum query planning time. **New in version 8.3** |
| `metrics``.planningTimeMicros``.min` | NumberLong | Literal | Minimum query planning time. **New in version 8.3** |
| `metrics``.planningTimeMicros``.sumOfSquares` | NumberDecimal | Literal | Sum of squares of query planning times. A high `sumOfSquares` value indicates high variance in the planning time for individual queries. **New in version 8.3** |
| `metrics``.numInterruptChecksPerSec` | NumberLong | Literal | Number of times a query operation calls `checkForInterrupt` per second. This metric becomes aggregated if you run the query in multiple batches using [`getMores`.](https://www.mongodb.com/docs/manual/reference/command/getmore.md#mongodb-dbcommand-dbcmd.getMore) **New in version 8.3** |
| `metrics``.overdueInterruptApproxMaxMillis` | NumberLong | Literal | Maximum number of milliseconds the system delayed `checkForInterrupt` for a sampled query operation. **New in version 8.3** |

### Plan Shape Counters

**New in version 9.0**

The `metrics.queryPlanner.planShapeCounters` document records how often MongoDB selected each plan shape for queries with the given key. Use these counters to learn which query plans your workload relies on most.

`planShapeCounters` contains up to three subdocuments, which each map counter names to counts:

| Subdocument | Description |
| --- | --- |
| `patterns` | Counts the overall shape of each winning plan. The patterns are mutually exclusive, so each query execution increments at most one pattern counter. |
| `nodes` | Counts the types of plan stages that appear in each winning plan. The node counters are not mutually exclusive, so one query execution can increment several of them. |
| `accessPaths` | Counts the data access paths and index bounds that each winning plan uses. The access path counters are not mutually exclusive, so one query execution can increment several of them. |

Each counter increments by at most one for each query execution, even if the plan uses the corresponding stage or access path many times. For example, a plan with 1,000 branches under an `$or` stage increments the matching `$or` node counter by one, not by 1,000. As a result, the counters record how many executions used a stage, not how many times each execution used it.

MongoDB omits counters with a count of zero and omits subdocuments that contain no counters. If none of the recorded queries produced plan shape counters, MongoDB omits the `planShapeCounters` document entirely. For example, a query that matches a single document by `_id` uses a fast path that doesn't match any tracked plan shape, so its query stats entry contains no `planShapeCounters` document.

MongoDB records plan shape counters only for the top-level query. For example, MongoDB does not record counters for the foreign side of a [`$lookup`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lookup.md#mongodb-pipeline-pipe.-lookup) stage.

#### Pattern Counters

Each pattern counter name lists the stages of the winning plan in order, starting with the access path stage. For example, `ixscanFetchSort` counts winning plans that use an index scan, fetch the matching documents, and then sort them.

Pattern names describe plans at a coarse level. They omit limit and skip stages, and they don't distinguish whether a stage applies a filter or which type of projection a plan uses. To determine those details, combine a pattern counter with the `nodes` counters and the [query shape](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-queryShape) for the entry.

`patterns` can contain the following counters:

| Access Path | Counters |
| --- | --- |
| Collection scan | `collscan`; `collscanProject`; `collscanProjectSort`; `collscanProjectSortProject`; `collscanSort`; `collscanSortProject`; `collscanSortProjectSort` |
| Index scan with a fetch | `ixscanFetch`; `ixscanFetchProject`; `ixscanFetchProjectSort`; `ixscanFetchProjectSortProject`; `ixscanFetchSort`; `ixscanFetchSortProject`; `ixscanFetchSortProjectSort`; `ixscanFetchSortMerge`; `ixscanFetchSortMergeProject` |
| Index scan with an `$or` | `ixscanFetchOr`; `ixscanFetchOrProject`; `ixscanFetchOrProjectSort`; `ixscanFetchOrSort`; `ixscanFetchOrSortProject`; `ixscanOrFetch`; `ixscanOrFetchProject`; `ixscanOrFetchProjectSort`; `ixscanOrFetchSort`; `ixscanOrFetchSortProject`; `ixscanOrProject`; `ixscanOrProjectSort` |
| Index scan without an immediate fetch | `ixscanProject`; `ixscanProjectSort`; `ixscanProjectSortProject`; `ixscanSortFetch`; `ixscanSortFetchProject`; `ixscanSortMergeFetch`; `ixscanSortMergeFetchProject`; `ixscanSortMergeProject` |

#### Node Counters

MongoDB records node counters after it selects the query execution engine, so the counters include the plan stages that represent aggregation stages pushed down to the [slot-based engine.](https://www.mongodb.com/docs/manual/reference/sbe.md#std-label-sbe-landing)

`nodes` can contain the following counters:

| Counter | Description |
| --- | --- |
| `collscanNoFilter``collscanWithFilter` | Collection scan stages, counted separately based on whether the stage applies a filter. |
| `ixscanNoFilter``ixscanWithFilter` | Index scan stages, counted separately based on whether the stage applies a filter. |
| `fetchNoFilter``fetchWithFilter` | Fetch stages, counted separately based on whether the stage applies a filter. |
| `andHashNoFilter``andHashWithFilter` | Hash-based index intersection stages, counted separately based on whether the stage applies a filter. |
| `andSorted` | Sorted index intersection stages. |
| `orNoFilterLte100Children``orWithFilterLte100Children``orNoFilterGt100Children``orWithFilterGt100Children` | `$or` stages, counted separately based on whether the stage applies a filter and whether the stage has more than 100 child stages. |
| `sortMergeNoFilterLte100Children``sortMergeWithFilterLte100Children``sortMergeNoFilterGt100Children``sortMergeWithFilterGt100Children` | Sort merge stages, counted separately based on whether the stage applies a filter and whether the stage has more than 100 child stages. |
| `returnKey` | Stages that return index keys instead of documents. |
| `shardingFilter` | Stages that filter out orphaned documents on a shard. |
| `projectionDefault``projectionCovered``projectionSimple` | Projection stages, counted separately by projection type. |
| `sortKeyGenerator` | Stages that generate sort keys for a sort. |
| `sortDefaultNoLimit``sortDefaultWithLimit``sortSimpleNoLimit``sortSimpleWithLimit` | Sort stages, counted separately by sort type and by whether the sort has a limit. |
| `limitSmall``limitMedium``limitLarge` | Limit stages, counted separately by limit value. `limitSmall` counts limits of 100 or less, `limitMedium` counts limits from 101 to 10,000, and `limitLarge` counts limits greater than 10,000. |
| `skipSmall``skipMedium``skipLarge` | Skip stages, counted separately by skip value. `skipSmall` counts skips of 100 or less, `skipMedium` counts skips from 101 to 10,000, and `skipLarge` counts skips greater than 10,000. |
| `textOr` | Stages that combine the results of a text search. |
| `match` | Match stages. |
| `replaceRoot` | Stages that replace the root of a document. |
| `group` | Group stages. |
| `eqLookupNoUnwind``eqLookupWithUnwind` | Equality lookup stages, counted separately based on whether the stage also unwinds the results. |
| `unpackTsBucket` | Stages that unpack [time series](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection) buckets. |
| `hashJoin``nlj``inlj``indexProbe` | Join stages, counted separately by join algorithm: hash join, nested loop join, indexed nested loop join, and index probe. |

#### Access Path Counters

`accessPaths` can contain the following counters:

| Counter | Description |
| --- | --- |
| `collscan``clusteredCollscan` | Collection scans, counted separately based on whether the scan uses the [clustered index.](https://www.mongodb.com/docs/manual/core/clustered-collections.md#std-label-clustered-collections) |
| `coveredIxscan` | Index scans that don't fetch documents. |
| `ixscanFetch` | Index scans that fetch documents. |
| `countScan` | Scans that count index keys without returning documents. |
| `distinctScan``distinctScanFetch` | Scans that skip duplicate index keys, counted separately based on whether the scan fetches documents. |
| `geoNear2d``geoNear2dSphere` | Geospatial proximity searches, counted separately based on whether the query uses a [2d](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2d.md#std-label-2d-index) or [2dsphere](https://www.mongodb.com/docs/manual/core/indexes/index-types/geospatial/2dsphere.md#std-label-2dsphere-index) index. |
| `textMatch` | Text searches that use a [text index.](https://www.mongodb.com/docs/manual/core/indexes/index-types/index-text.md#std-label-index-type-text) |
| `otherAccessPath` | Winning plans that don't use a collection scan, an index scan, a count scan, a distinct scan, or a geospatial access path. A plan that only performs a text search increments both `textMatch` and `otherAccessPath`. |
| `btreeIxscan``wildcardIxscan``sparseIxscan``uniqueIxscan``hashedIxscan``multikeyIxscan` | Index scans, counted separately by index property. A single index scan can increment multiple of these counters. |
| `boundsFullScan``boundsPoint``boundsBoundedRange``boundsMinKeyToValue``boundsValueToMaxKey``boundsMixture` | Index scans, counted separately by the index bounds that the scan uses. MongoDB increments `boundsMixture` when the scan uses more than one type of bound. |
| `boundsUnionedSmall``boundsUnionedLarge` | Index scans where a field has multiple bounds, counted separately by the number of bounds. `boundsUnionedSmall` counts fields with 2 to 50 bounds, and `boundsUnionedLarge` counts fields with 51 or more bounds. |

### Collection Type

The `key.collectionType` field indicates the type of collection that the recorded query was issued on. The `collectionType` can be one of the following values:

| Field | Description |
| --- | --- |
| `changeStream` | The query was a [change stream operation.](https://www.mongodb.com/docs/manual/changestreams.md#std-label-changeStreams) |
| `collection` | The query was issued on a standard [collection.](https://www.mongodb.com/docs/manual/core/databases-and-collections.md#std-label-collections) |
| `nonExistent` | The query was issued on a collection that does not exist. |
| `timeseries` | The query was issued on a [timeseries collection.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection) |
| `view` | The query was issued on a [view.](https://www.mongodb.com/docs/manual/core/views.md#std-label-views-landing-page) |
| `virtual` | The query was issued on a virtual collection. The following operations occur in virtual collections: [`$currentOp`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/currentop.md#mongodb-pipeline-pipe.-currentOp); [`$documents`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/documents.md#mongodb-pipeline-pipe.-documents); [`$listLocalSessions`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/listlocalsessions.md#mongodb-pipeline-pipe.-listLocalSessions); [`$queryStats`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#mongodb-pipeline-pipe.-queryStats) |

### Query Shape

The `key.queryShape` document contains query shape fields. To learn about query shapes, see [Query Shapes.](https://www.mongodb.com/docs/manual/core/query-shapes.md#std-label-query-shapes)

The fields in `key.queryShape` vary based on the command that resulted in the query stats entry. `$queryStats` creates query stats entries for [`aggregate`](https://www.mongodb.com/docs/manual/reference/command/aggregate.md#mongodb-dbcommand-dbcmd.aggregate), [`find`](https://www.mongodb.com/docs/manual/reference/command/find.md#mongodb-dbcommand-dbcmd.find), [`distinct`](https://www.mongodb.com/docs/manual/reference/command/distinct.md#mongodb-dbcommand-dbcmd.distinct), [`count`](https://www.mongodb.com/docs/manual/reference/command/count.md#mongodb-dbcommand-dbcmd.count), [`update`](https://www.mongodb.com/docs/manual/reference/command/update.md#mongodb-dbcommand-dbcmd.update), [`insert`](https://www.mongodb.com/docs/manual/reference/command/insert.md#mongodb-dbcommand-dbcmd.insert), and [`delete`](https://www.mongodb.com/docs/manual/reference/command/delete.md#mongodb-dbcommand-dbcmd.delete) commands.

Each query shape property corresponds to a query option. For example, `key.queryShape.sort` corresponds to the [`sort()`](https://www.mongodb.com/docs/manual/reference/method/cursor.sort.md#mongodb-method-cursor.sort) specification for the query shape.

#### find Command Query Shape

The following table describes the query shape properties for `find` commands.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.filter` | Document | Normalized |
| `key.queryShape.sort` | Document | Literal |
| `key.queryShape.projection` | Document | Normalized |
| `key.queryShape.skip` | Integer | Normalized |
| `key.queryShape.limit` | Integer | Normalized |
| `key.queryShape.singleBatch` | Boolean | Literal |
| `key.queryShape.max` | Document | Normalized |
| `key.queryShape.min` | Document | Normalized |
| `key.queryShape.returnKey` | Boolean | Literal |
| `key.queryShape.showRecordId` | Boolean | Literal |
| `key.queryShape.tailable` | Boolean | Literal |
| `key.queryShape.oplogReplay` | Boolean | Literal |
| `key.queryShape.awaitData` | Boolean | Literal |
| `key.queryShape.collation` | Document | Literal |
| `key.queryShape.allowDiskUse` | Boolean | Literal |
| `key.queryShape.let` | Document | Normalized |

#### aggregate Command Query Shape

The following table describes the query shape properties for `aggregate` commands.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.pipeline` | Array | Normalized |
| `key.queryShape.explain` | Boolean | Literal |
| `key.queryShape.allowDiskUse` | Boolean | Literal |
| `key.queryShape.allowPartialResults` | Boolean | Literal |
| `key.queryShape.collation` | Document | Literal |
| `key.queryShape.hint` | String or Document | Normalized |
| `key.queryShape.let` | Document | Normalized |

#### distinct Command Query Shape

The following table describes the query shape properties for `distinct` commands.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.collation` | Document | Normalized |
| `key.queryShape.key` | String | Literal |
| `key.queryShape.query` | Document | Normalized |

#### count Command Query Shape

The following table describes the query shape properties for `count` commands.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.collation` | Document | Normalized |
| `key.queryShape.query` | Document | Normalized |
| `key.queryShape.limit` | Integer | Normalized |
| `key.queryShape.skip` | Integer | Normalized |

#### update Command Query Shape

**New in version 9.0**

The following table describes the query shape properties for `update` commands. `$queryStats` tracks query shape statistics for each update statement in the `updates` array, not for the top-level `update` command as a whole.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.q` | Document | Normalized |
| `key.queryShape.u` | Document or Array | Normalized |
| `key.queryShape.c` | Document | Normalized |
| `key.queryShape.arrayFilters` | Array of documents | Normalized |
| `key.queryShape.multi` | Boolean | Literal |
| `key.queryShape.upsert` | Boolean | Literal |
| `key.queryShape.let` | Document | Normalized |
| `key.queryShape.collation` | Document | Literal |

**Important:**

`$queryStats` does not collect query shape statistics for `update` operations on [time series collections.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection)

#### insert Command Query Shape

**New in version 9.0**

The following table describes the query shape properties for `insert` commands. `$queryStats` tracks query shape statistics once for the entire `insert` command, not for each document in the `documents` array. MongoDB always normalizes `documents` to a fixed placeholder value, regardless of the number or contents of the inserted documents.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.documents` | Array | Normalized |

**Important:**

`$queryStats` does not collect query shape statistics for `insert` operations on [time series collections.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection)

#### delete Command Query Shape

**New in version 9.0**

The following table describes the query shape properties for `delete` commands. `$queryStats` tracks query shape statistics for each delete statement in the `deletes` array, not for the top-level `delete` command as a whole.

`key.queryShape.limit` reflects the `limit` field of the delete statement, where `0` deletes all matching documents and `1` deletes a single document. It does not cap the number of query stats entries.

| Field | Type | Literal or Normalized |
| --- | --- | --- |
| `key.queryShape.q` | Document | Normalized |
| `key.queryShape.limit` | Integer | Literal |
| `key.queryShape.let` | Document | Normalized |
| `key.queryShape.collation` | Document | Literal |

**Important:**

`$queryStats` does not collect query shape statistics for `delete` operations on [time series collections.](https://www.mongodb.com/docs/manual/core/timeseries-collections.md#std-label-manual-timeseries-collection)

### Supplemental Metrics

Query stats entries may contain a `metrics.supplementalMetrics` document that provides additional information about your queries.

#### $vectorSearch Metrics

If your query shape contains [`$vectorSearch`](https://www.mongodb.com/docs/vector-search/query/aggregation-stages/vector-search-stage.md#mongodb-pipeline-pipe.-vectorSearch), `$queryStats` outputs the following supplemental metrics:

| Field | Type | Description |
| --- | --- | --- |
| `metrics``.supplementalMetrics``.vectorSearch` | Document | Supplemental metrics about a `$vectorSearch` aggregation stage |
| `metrics``.supplementalMetrics``.vectorSearch``.limit` | Document | Metrics related to the `limit` value of the `$vectorSearch` aggregation stage |
| `metrics``.supplementalMetrics``.vectorSearch``.numCandidatesLimitRatio` | Document | Metrics related to the `numCandidates` value of the `$vectorSearch` aggregation stage. `$queryStats` expresses these metrics as a ratio of `numCandidates` divided by the `limit` value. |

## Examples

### MongoDB Shell

To run the examples in this section, start with the following data:

```javascript
db.products.insertMany(
  [
    { item: "card", qty: 15 },
    { item: "envelope", qty: 20 },
    { item: "stamps" , qty: 30 }
  ]
)
```

Then, run these commands:

```javascript
db.products.find( { item: "card" } )

db.products.aggregate( [
    {
      $match: { qty: { $gt: 20 } }
    }
] )
```

The following examples show the output of `$queryStats` using different types of data transformation:

- [Untransformed Example](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-example-untransformed)

- [Transformed Example](https://www.mongodb.com/docs/manual/reference/operator/aggregation/querystats.md#std-label-queryStats-example-transformed)

The example `$queryStats` output in the following sections may vary based on the execution of other commands.

### Untransformed Example

Input:

```javascript
db.getSiblingDB("admin").aggregate( [
    {
      $queryStats: { }
    }
] )
```

Output:

```javascript
[
  {
    key: {
      queryShape: {
        cmdNs: { db: 'test', coll: 'products' },
        command: 'find',
        filter: { item: { '$eq': '?string' } }
      },
      client: {
        driver: { name: 'nodejs|mongosh', version: '5.1.0' },
        os: {
          type: 'Darwin',
          name: 'darwin',
          architecture: 'arm64',
          version: '22.6.0'
        },
        platform: 'Node.js v16.19.1, LE (unified)',
        version: '5.1.0|1.8.0',
        application: { name: 'mongosh 1.8.0' }
      },
      collectionType: 'collection'
    },
    keyHash: 'dsoJ+LHAru0z6MJ1/IygJnnLTrlpVYYmPnlmNZbZrLI=',
    queryShapeHash: "uxMLCvpiJ5N/IRqt4c28/0A8F01C8AA16CA805FF5C1A5737535F97E40C2A90CE91A82CCB7A74C7CCB9C48",
    metrics: {
      lastExecutionMicros: Long("4254"),
      execCount: Long("1"),
      totalExecMicros: {
        sum: Long("4254"),
        max: Long("4254"),
        min: Long("4254"),
        sumOfSquares: Decimal128("18096516")
      },
      firstResponseExecMicros: {
        sum: Long("4254"),
        max: Long("4254"),
        min: Long("4254"),
        sumOfSquares: Decimal128("18096516")
      },
      docsReturned: {
        sum: Long("1"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("1")
      },
      planningTimeMicros: {
        sum: Long("2150"),
        max: Long("2150"),
        min: Long("2150"),
        sumOfSquares: Decimal128("4622500")
      },
      costBasedRanker: {
        cardinalityEstimationMethods: {
          Histogram: Long("0"),
          Sampling: Long("0"),
          Heuristics: Long("0"),
          Mixed: Long("0"),
          Metadata: Long("0"),
          Code: Long("0")
        },
        nDocsSampled: {
          sum: Long("0"),
          max: Long("0"),
          min: Long("0"),
          sumOfSquares: Decimal128("0")
        }
      },
      firstSeenTimestamp: ISODate("2023-09-14T12:30:27.989Z"),
      latestSeenTimestamp: ISODate("2023-09-14T12:30:27.989Z")
    },
    asOf: Timestamp({ t: 1694695007, i: 0 })
  },
  {
    key: {
      queryShape: {
        cmdNs: { db: 'test', coll: 'products' },
        command: 'aggregate',
        pipeline: [
          { '$match': { qty: { '$gt': '?number' } } }
        ]
      },
      apiVersion: '1',
      client: {
        driver: { name: 'nodejs|mongosh', version: '5.1.0' },
        os: {
          type: 'Darwin',
          name: 'darwin',
          architecture: 'arm64',
          version: '22.6.0'
        },
        platform: 'Node.js v16.19.1, LE (unified)',
        version: '5.1.0|1.8.0',
        application: { name: 'mongosh 1.8.0' }
      },
      collectionType: 'collection',
      cursor: { batchSize: '?number' }
    },
    keyHash: '2QLBfL0m1lliStdN4XvBjqVBtZQ6ffaB2L1pJ99twT8=',
    queryShapeHash: "uxMLCvpiJ5N/IRqt4c28/0A8F01C8AA16CA805FF5C1A5737535F97E40C2A90CE91A82CCB7A74C7CCB9C48",
    metrics: {
      lastExecutionMicros: Long("350"),
      execCount: Long("3"),
      totalExecMicros: {
        sum: Long("3084"),
        max: Long("2499"),
        min: Long("235"),
        sumOfSquares: Decimal128("6422726")
      },
      firstResponseExecMicros: {
        sum: Long("3084"),
        max: Long("2499"),
        min: Long("235"),
        sumOfSquares: Decimal128("6422726")
      },
      docsReturned: {
        sum: Long("3"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("3")
      },
      planningTimeMicros: {
        sum: Long("1850"),
        max: Long("850"),
        min: Long("420"),
        sumOfSquares: Decimal128("1252500")
      },
      costBasedRanker: {
        cardinalityEstimationMethods: {
          Histogram: Long("0"),
          Sampling: Long("0"),
          Heuristics: Long("0"),
          Mixed: Long("0"),
          Metadata: Long("0"),
          Code: Long("0")
        },
        nDocsSampled: {
          sum: Long("0"),
          max: Long("0"),
          min: Long("0"),
          sumOfSquares: Decimal128("0")
        }
      },
      firstSeenTimestamp: ISODate("2023-11-29T21:16:17.796Z"),
      latestSeenTimestamp: ISODate("2023-11-29T21:17:12.385Z")
    },
    asOf: Timestamp({ t: 1701292827, i: 0 })
  }
]
```

### Transformed Example

Input:

```javascript
db.getSiblingDB("admin").aggregate( [
    {
      $queryStats: {
          transformIdentifiers: {
            algorithm: "hmac-sha-256" ,
            hmacKey: BinData(8, "87c4082f169d3fef0eef34dc8e23458cbb457c3sf3n2")
          }
        }
    }
  ] )
```

Output:

```javascript
[
  {
    key: {
      queryShape: {
        cmdNs: {
          db: 'Mtrt3iG7dsX5c5uCSIhSVlcu5qD3u3xx2EQnS1dJLxM=',
          coll: '3oJE6AyOuf8h5NqWiXETxulFlPm3QUXbMnMjL2EqAU4='
        },
        command: 'find',
        filter: {
          'VWVRow7Ure92ajRPfrpWiU8OtDeWcLePFIq0+tooBng=': { '$eq': '?string' }
        }
      },
      client: {
        driver: { name: 'nodejs|mongosh', version: '5.1.0' },
        os: {
          type: 'Darwin',
          name: 'darwin',
          architecture: 'arm64',
          version: '22.6.0'
        },
        platform: 'Node.js v16.19.1, LE (unified)',
        version: '5.1.0|1.8.0',
        application: { name: 'mongosh 1.8.0' }
      },
      collectionType: 'collection'
    },
    keyHash: 'q4vxam+wbk8tTrl8D0MDFH1LQAbI8fWspfkGKhEUROk=',
    queryShapeHash: "uxMLCvpiJ5N/IRqt4c28/0A8F01C8AA16CA805FF5C1A5737535F97E40C2A90CE91A82CCB7A74C7CCB9C48",
    metrics: {
      lastExecutionMicros: Long("4254"),
      execCount: Long("1"),
      keysExamined: {
        sum: Int("5"),
        max: Long("5"),
        min: Long("5"),
        sumOfSquares: Decimal128("25")
      },
      docsExamined: {
        sum: Long("1"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("1")
      },
      hasSortStage: {true: Long("0"), false: Long("1")},
      usedDisk: {true: Long("0"), false: Long("1")},
      fromMultiPlanner: {true: Long("0"), false: Long("1")},
      fromPlanCache: {true: Long("1"), false: Long("0")},
      totalExecMicros: {
        sum: Long("4254"),
        max: Long("4254"),
        min: Long("4254"),
        sumOfSquares: Decimal128("18096516")
      },
      firstResponseExecMicros: {
        sum: Long("4254"),
        max: Long("4254"),
        min: Long("4254"),
        sumOfSquares: Decimal128("18096516")
      },
      docsReturned: {
        sum: Long("1"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("1")
      },
      planningTimeMicros: {
        sum: Long("2150"),
        max: Long("2150"),
        min: Long("2150"),
        sumOfSquares: Decimal128("4622500")
      },
      costBasedRanker: {
        cardinalityEstimationMethods: {
          Histogram: Long("0"),
          Sampling: Long("0"),
          Heuristics: Long("0"),
          Mixed: Long("0"),
          Metadata: Long("0"),
          Code: Long("0")
        },
        nDocsSampled: {
          sum: Long("0"),
          max: Long("0"),
          min: Long("0"),
          sumOfSquares: Decimal128("0")
        }
      },
      firstSeenTimestamp: ISODate("2023-09-14T12:30:27.989Z"),
      latestSeenTimestamp: ISODate("2023-09-14T12:30:27.989Z")
    },
    asOf: Timestamp({ t: 1694695712, i: 0 })
  },
  {
    key: {
      queryShape: {
        cmdNs: {
          db: 'Mtrt3iG7dsX5c5uCSIhSVlcu5qD3u3xx2EQnS1dJLxM=',
          coll: '3oJE6AyOuf8h5NqWiXETxulFlPm3QUXbMnMjL2EqAU4='
        },
        command: 'aggregate',
        pipeline: [
          {
            '$match': {
              'RVqrwNEPotzdKnma/T7s4YcgNvpqO29BMDoni2N4IMI=': { '$gt': '?number' }
            }
          }
        ]
      },
      apiVersion: '1',
      client: {
        driver: { name: 'nodejs|mongosh', version: '5.1.0' },
        os: {
          type: 'Darwin',
          name: 'darwin',
          architecture: 'arm64',
          version: '22.6.0'
        },
        platform: 'Node.js v16.19.1, LE (unified)',
        version: '5.1.0|1.8.0',
        application: { name: 'mongosh 1.8.0' }
      },
      collectionType: 'collection',
      cursor: { batchSize: '?number' }
    },
    keyHash: 'HEhpQTYB+/wVoHLkOkMd+EC2jguQlMJ1N/vTE7+b8Js=',
    queryShapeHash: "uxMLCvpiJ5N/IRqt4c28/0A8F01C8AA16CA805FF5C1A5737535F97E40C2A90CE91A82CCB7A74C7CCB9C48",
    metrics: {
      lastExecutionMicros: Long("350"),
      execCount: Long("3"),
      keysExamined: {
        sum: Int("5"),
        max: Long("5"),
        min: Long("5"),
        sumOfSquares: Decimal128("25")
      },
      docsExamined: {
        sum: Long("1"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("1")
      },
      hasSortStage: {true: Long("0"), false: Long("1")},
      usedDisk: {true: Long("0"), false: Long("1")},
      fromMultiPlanner: {true: Long("0"), false: Long("1")},
      fromPlanCache: {true: Long("1"), false: Long("0")},
      totalExecMicros: {
        sum: Long("3084"),
        max: Long("2499"),
        min: Long("235"),
        sumOfSquares: Decimal128("6422726")
      },
      firstResponseExecMicros: {
        sum: Long("3084"),
        max: Long("2499"),
        min: Long("235"),
        sumOfSquares: Decimal128("6422726")
      },
      docsReturned: {
        sum: Long("3"),
        max: Long("1"),
        min: Long("1"),
        sumOfSquares: Decimal128("3")
      },
      planningTimeMicros: {
        sum: Long("1850"),
        max: Long("850"),
        min: Long("420"),
        sumOfSquares: Decimal128("1252500")
      },
      costBasedRanker: {
        cardinalityEstimationMethods: {
          Histogram: Long("0"),
          Sampling: Long("0"),
          Heuristics: Long("0"),
          Mixed: Long("0"),
          Metadata: Long("0"),
          Code: Long("0")
        },
        nDocsSampled: {
          sum: Long("0"),
          max: Long("0"),
          min: Long("0"),
          sumOfSquares: Decimal128("0")
        }
      },
      firstSeenTimestamp: ISODate("2023-11-29T21:16:17.796Z"),
      latestSeenTimestamp: ISODate("2023-11-29T21:17:12.385Z")
    },
    asOf: Timestamp({ t: 1701293302, i: 0 })
  },
]
```

## MongoDB Atlas Data Collection

MongoDB Atlas periodically uses `$queryStats` to collect anonymized data about your queries, which helps improve MongoDB products. Your data may also be used to make feature suggestions based on usage. MongoDB retains the data it collects with `$queryStats` for four years.

When Atlas runs `$queryStats` on your deployment, it uses a unique HMAC key per Atlas organization to transform your data and avoid collecting sensitive information.
