← Files MongoDB AtlasARCHIVED FILE

references/source-query-stats.md

3.35 KB · Sep 30, 2026 · 22:47 UTC

↓ Download file

# Query Stats

## When to use

Analyzes query access patterns with minimal performance overhead. Use for identifying co-accessed fields, collection relationships, and query frequencies. Only supports `find`, `aggregate`, and `distinct` operations.

## Requirements

Atlas M10+ tier.

## How to use

Aggregate on the admin database.

With mcp-server, use the `mcp__mongodb__aggregateDB` tool with database set to `admin`.

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

**Example 1: Find collections frequently queried together with others (embedding candidates)**
```javascript
db.aggregate([
  { $queryStats: {} },
  {
    $match: {
      "key.queryShape.cmdNs.db": "databaseName",
      "key.queryShape.command": "aggregate",
      "key.queryShape.pipeline.$lookup": { $exists: true }
    }
  },
  { $unwind: "$key.queryShape.pipeline" },
  { 
    $match: { "key.queryShape.pipeline.$lookup": { $exists: true } } 
  },
  { 
    $set: { 
      stageKeyValue: { 
        $first: { $objectToArray: "$key.queryShape.pipeline" } 
      } 
    }
  },
  { 
    $group: {
      _id: { 
        source: "$key.queryShape.cmdNs.coll",
        target: "$stageKeyValue.v.from"
      },
      totalLookupHits: { $sum: "$metrics.execCount" },
      avgPipelineMs: {
        $avg: { $divide: [
          { $divide: ["$metrics.totalExecMicros.sum", 1000] },
          "$metrics.execCount"
        ]}
      }
    }
  },
  { $sort: { totalLookupHits: -1 } }
])

// High totalLookupHits = frequently joined 
// High avgPipelineMS = lookup is part of slow queries (does not automatically mean that the $lookup is slow, could be the whole pipeline - see the full query shapes)
// High scores on both - consider embedding to avoid $lookup 
```

**Example 1.1: Find query shapes that use $lookup on specific collections**
```javascript
db.aggregate([
  { $queryStats: {} },
  {
    $match: {
      "key.queryShape.cmdNs.db": "databaseName",
      "key.queryShape.command": "aggregate",
      "key.queryShape.cmdNs.coll": "sourceCollectionName",
      "key.queryShape.pipeline.$lookup.from": "targetCollectionName"
    }
  },
  {
    $project: {
      database: "$key.queryShape.cmdNs.db",
      collection: "$key.queryShape.cmdNs.coll",
      pipeline: "$key.queryShape.pipeline",
      execCount: "$metrics.execCount",
      avgMs: {
          $divide: [
            { $divide: ["$metrics.totalExecMicros.sum", 1000] },
            "$metrics.execCount"
          ]
      }
    },
  },
  { $sort: { execCount: -1 } },
  { $limit: 10 }
])
```

**Example 2: Find top most frequent query shapes (optimize hot paths)**
```javascript
db.getSiblingDB("admin").aggregate([
  { $queryStats: {} },
  { $sort: { "metrics.execCount": -1 } },
  { $limit: 10 },
  {
    $project: {
      command: "$key.queryShape.command",
      database: "$key.queryShape.cmdNs.db",
      collection: "$key.queryShape.cmdNs.coll",
      queryShape: "$key.queryShape",
      execCount: "$metrics.execCount",
      avgMs: {
        $divide: [
          { $divide: ["$metrics.totalExecMicros.sum", 1000] },
          "$metrics.execCount"
        ]
      }
    }
  }
])

// High execCount = hot path → design your schema for these queries first
// Cross reference with avgMS or [slow query logs](references/source-slow-query-logs.md) to find queries that are both frequent and slow
// Note: Query stats do not include write patterns (update, insert)
```

SHA-256: e4cef5c876ade4474452405aab4776e4439bc3a59610a1de17b7db0b4ab397d2