$queryStats(聚合)
在此页面上
定义
警告
$queryStats
聚合阶段不受支持,也不能保证在未来版本中保持稳定。 不要构建依赖于此阶段的特定输出格式的功能,因为输出可能会在将来的版本中发生变化。
返回已记录查询的运行时统计信息。
$queryStats
收集并报告 aggregate()
、 find()
和distinct()
查询的指标。 $queryStats
不收集使用Queryable Encryption的查询信息。
要求
$queryStats
阶段在集群层至少为 M 10的 MongoDB Atlas上托管的部署上启用。
要运行$queryStats
阶段,您的管道必须满足以下要求:
管道必须在
admin
数据库上运行。$queryStats
必须是管道的第一阶段。
语法
db.adminCommand( { aggregate: 1, pipeline: [ { $queryStats: { transformIdentifiers: { algorithm: <string>, hmacKey: <binData> /* subtype 8 - used for sensitive data */ } } } ], cursor: { } } )
重要
您无法在特定集合上运行$queryStats
。 有关完整示例,请参阅示例。
命令字段
$queryStats
采用以下字段:
字段 | 必要性 | 类型 | 说明 |
---|---|---|---|
transformIdentifiers | Optional | 文档 | 为 $queryStats 输出指定其他转换选项。 |
transformIdentifiers .algorithm | 如果指定 transformIdentifiers 对象,则为必填项 | 字符串 | 应用于输出中的命名空间信息和字段名称的哈希转换类型。 当前唯一支持的 algorithm 值为hmac-sha-256 。 |
transformIdentifiers .hmacKey | 如果指定 transformIdentifiers 对象,则为必填项 | BinData | HMAC 转换中输入的私钥。 |
访问控制
如果您的部署强制执行访问控制,则运行$queryStats
的用户必须具有以下权限:
要运行不带
transformIdentifiers
选项的$queryStats
,用户必须具有queryStatsRead
权限操作。要使用
transformIdentifiers
选项运行$queryStats
,用户必须同时具有queryStatsRead
和queryStatsReadTransformed
权限操作。
内置clusterMonitor
角色提供queryStatsRead
和queryStatsReadTransformed
权限。以下示例授予对admin
数据库的clusterMonitor
角色:
db.grantRolesToUser( "<user>", [ { role: "clusterMonitor", db: "admin" } ] )
行为
以下部分描述了$queryStats
阶段的行为细节。
$queryStats 如何追踪查询统计信息
$queryStats
阶段的统计信息在内存中存储的虚拟集合中进行跟踪。 虚拟collection的内存限制为系统总内存的 1%。
$queryStats 如何对返回的文档进行分组
$queryStats
将具有共同属性的查询分组到同一输出文档中。 生成的文档称为查询统计条目。
$queryStats
通过将用户提供的字段值规范化为其数据类型,将类似的查询分组在一起。 例如,指定为{ item: 'card' }
的筛选器将规范化为{ item :
'?string'}
。 $queryStats
还会规范化某些查询选项(如hint
和comment
的值。
$queryStats
保留readConcern
和readPreference
等选项的字面值。
有关查询统计条目中包含的完整选项列表,请参阅find 命令查询结构。
$queryStats 如何使用transformIdentifiers 转换数据
当为transformIdentifiers
选项指定了 HMAC 密钥时, $queryStats
使用该 HMAC 密钥对以下数据应用 HMAC-SHA-256 哈希函数:
文档字段名称
集合名称
数据库名称
$queryStats
不会对以下数据应用 HMAC 转换:
MQL 关键字,例如操作符名称(例如
$gte
)。参数名称,例如
$setWindowFields
中的partitionBy
参数。字段值。
$queryStats
在记录查询时将查询中的字段值规范为其数据类型(例如数字或字符串)。$queryStats
从不存储包含用户数据的字段值。
有关转换后的输出的示例,请参阅转换后的示例。
$queryStats Log Entries
MongoDB在部署日志中记录$queryStats
操作。 默认, MongoDB仅记录$queryStats
操作的调用,而不记录操作的输出。 对于包含transformIdentifiers
选项的$queryStats
操作,您可以指定日志条目中是否包含转换后的输出。
要了解如何控制$queryStats
日志行为,请参阅切换 $queryStats 日志输出。
Change Streams
发生以下事件之一时,变更流的查询统计信息会更新:
创建游标
getMore
操作完成游标关闭
为变更流报告的查询统计信息具有以下行为:
totalExecMicros
等执行指标包含最近操作(游标创建、getMore
或游标关闭)的信息。内部
getMore
操作会递增execCount
指标。firstResponseExecMicros
和totalExecMicros
始终相同,因为会为每个getMore
操作收集和更新统计信息。当游标关闭时,
lastExecutionMicros
为0 。
输出
$queryStats
返回查询统计信息条目的数组。 某些查询统计信息条目属性包含字面值,某些属性已标准化以对常见查询进行分组。
查询统计信息条目包含以下顶级文档:
文档 | 说明 |
---|---|
key | 用于定义查询统计信息输出中的条目的唯一属性组合。
每个唯一的属性组合都会在 |
asOf | $queryStats 从$queryStats 虚拟collection中读取此条目时的 UTC 时间。asOf 不一定会为每个结果返回相同的 UTC 时间。 在内部,数据结构被分区,每个分区将在单独的时间点读取。 |
metrics | 包含与每个查询统计信息条目关联的聚合运行时指标。 每个查询统计信息条目都记录共享相同密钥的每个查询的统计信息。 |
输出数组中的每个文档都包含以下字段:
字段 | 类型 | 字面值或规范化值 | 说明 |
---|---|---|---|
key | 文档 | $literal | 包含查询结构和将一组查询分组在一起的其他查询属性 |
key.queryShape | 文档 | $literal | 包含用于将相似查询群组在一起的属性。 有关详细信息,请参阅查询结构。 |
key.client | 文档 | $literal | 描述与密钥关联的客户端信息 |
key.client.application | 文档 | $literal | 客户端应用程序名称 |
key.client.driver | 文档 | $literal | 描述用于发出查询的驱动程序 |
key.client.driver.name | 字符串 | $literal | 用于发出查询的驱动程序的名称。 可能的值包括 mongosh 和nodejs 。 |
key.client.driver.version | 字符串 | $literal | 用于发出查询的驱动程序的版本号 |
key.client.os | 文档 | $literal | 描述发出查询的客户端使用的操作系统 |
key.client.os.type | 字符串 | $literal | 操作系统类型 |
key.client.os.name | 字符串 | $literal | 操作系统名称 |
key.client.os.architecture | 字符串 | $literal | 操作系统的架构。 可能的值包括 arm64 和x86_64 。 |
key.client.os.version | 字符串 | $literal | 操作系统的版本号 |
key.readConcern | 文档 | $literal | |
key.collectionType | 字符串 | $literal | 发出查询的集合类型。 有关详细信息,请参阅集合类型。 |
key.hint | 文档或字符串 | 标准化 | 用作查询提示的索引 |
key.batchSize | 字符串 | 标准化 | 键的批处理大小。 批处理大小指定来自 MongoDB 实例的每批响应中要返回的文档数量。 |
key.comment | 字符串 | 标准化 | 与键关联的注释 |
key.maxTimeMS | 字符串 | 标准化 | 与键关联的maxTimeMS值 |
key.noCursorTimeout | 布尔 | 标准化 | 与键关联的noCursorTimeout选项 |
key.allowPartialResults | 字符串 | $literal | 与键关联的allowPartialResults选项 |
key.readPreference | 字符串 | $literal | |
key.apiVersion | 字符串 | $literal | 与密钥关联的 Stable API 版本。 请参阅stable API。 |
key.apiStrict | 布尔 | $literal | 与键关联的 apiStrict 参数值。 请参阅stable API 参数。 |
key.apiDeprecationErrors | 布尔 | $literal | 与键关联的 apiDeprecationErrors 参数值。 请参阅stable API 参数。 |
keyHash | 字符串 | $literal | key 中值的哈希表示。 每个唯一的keyHash 值对应于$queryStats 内存存储中的一个唯一条目。 |
metrics | 文档 | $literal | 描述密钥的运行时统计信息 |
metrics.lastExecutionMicros | NumberLong | $literal | 具有给定键的所有查询的最新查询的执行运行时 |
metrics.execCount | NumberLong | $literal | 已执行具有给定键的查询的次数 |
metrics.keysExamined | 文档 | $literal | 描述查询检查的键的数量 |
metrics .keysExamined .sum | 整型 | $literal | 检查的键总数 |
metrics .keysExamined .max | NumberLong | $literal | 检查的最大键数 |
metrics .keysExamined .min | NumberLong | $literal | 检查的键数量最少 |
metrics .keysExamined .sumOfSquares | NumberDecimal | $literal | 检查的键数量的平方和。
|
metrics.docsExamined | 文档 | $literal | 描述查询检查的文档数量 |
metrics .docsExamined .sum | 整型 | $literal | 查询中检查的文档总数 |
metrics .docsExamined .max | NumberLong | $literal | 检查的最大文档数 |
metrics .docsExamined .min | NumberLong | $literal | 最少检查文件数量 |
metrics .docsExamined .sumOfSquares | NumberDecimal | $literal | 检查的文档数量的平方和。
|
metrics.hasSortStage | 布尔 | $literal | true 当MongoDB在从游标接收到文档后必须对文档进行排序时。 |
metrics.usedDisk | 布尔 | $literal | true 当查询由于内存限制将数据写入临时文件时。 |
metrics.fromMultiPlanner | 布尔 | $literal | true 当查询规划器在为查询选择获胜执行计划之前评估多个计划时。 |
metrics.fromPlanCache | 布尔 | $literal | true 当查询规划器能够使用计划缓存中的计划时。 |
metrics.totalExecMicros | 文档 | $literal | 描述使用给定键运行查询所花费的总时间。 如果查询结果为
|
metrics .totalExecMicros .sum | NumberLong | $literal | 使用给定键运行查询所花费的总时间 |
metrics .totalExecMicros .max | NumberLong | $literal | 使用给定键运行查询所花费的最长时间 |
metrics .totalExecMicros .min | NumberLong | $literal | 使用给定键运行查询所花费的最短时间 |
metrics .totalExecMicros .sumOfSquares | NumberDecimal | $literal | 具有给定键的所有查询的总执行时间的平方和。 sumOfSquares 值较高表示查询执行时间的差异较大。 |
metrics .firstResponseExecMicros | 文档 | $literal | 描述从键内的查询开始处理到服务器返回第批处理结果所花费的时间
|
metrics .firstResponseExecMicros .sum | NumberLong | $literal | 从查询处理开始到服务器返回第一批处理结果所花费的总时间 |
metrics .firstResponseExecMicros .max | NumberLong | $literal | 从查询处理开始到服务器返回第一批处理结果所花费的最长时间 |
metrics .firstResponseExecMicros .min | NumberLong | $literal | 从查询处理开始到服务器返回第一批处理结果所用的最短时间 |
metrics .firstResponseExecMicros .sumOfSquares | NumberDecimal | $literal | 从查询处理开始到服务器返回第一批处理结果所用时间的平方和。
|
metrics.docsReturned | 文档 | $literal | 描述键内查询返回的文档数量 |
metrics .docsReturned .sum | NumberLong | $literal | 使用给定键的查询返回的文档总数 |
metrics .docsReturned .max | NumberLong | $literal | 使用给定键的查询返回的最大文档数 |
metrics .docsReturned .min | NumberLong | $literal | 使用给定键的查询返回的最少文档数 |
metrics .docsReturned .sumOfSquares | NumberDecimal | $literal | 查询在键内返回的文档数量的平方和。
|
metrics.firstSeenTimestamp | Date | $literal | 自上次重启以来首次使用具有给定键的查询的时间 |
metrics.lastSeenTimestamp | Date | $literal | 最近一次使用具有给定键的查询的时间 |
collectionType
key.collectionType
字段表示发出记录查询的集合类型。 collectionType
可以是以下值之一:
字段 | 说明 |
---|---|
changeStream | 该查询是change stream操作。 |
collection | 查询是对标准集合发出的。 |
nonExistent | 对不存在的collection发出查询。 |
timeseries | 该查询是对时间序列collection发出的。 |
view | 查询是对视图发出的。 |
virtual | 该查询是对虚拟集合发出的。 以下操作发生在虚拟collection中: |
查询结构
key.queryShape
文档包含查询结构字段。 要学习;了解查询形状,请参阅查询形状。
key.queryShape
中的字段因生成查询统计条目的命令而异。 $queryStats
为aggregate
、 find
和distinct
命令创建查询统计信息条目。
每个查询结构属性都对应一个查询选项。 例如, key.queryShape.sort
对应于查询结构的sort()
规范。
find 命令查询结构
下表描述了find
命令的查询结构属性。
字段 | 类型 | 字面值或规范化值 |
---|---|---|
key.queryShape.filter | 文档 | 标准化 |
key.queryShape.sort | 文档 | $literal |
key.queryShape.projection | 文档 | 标准化 |
key.queryShape.skip | 整型 | 标准化 |
key.queryShape.limit | 整型 | 标准化 |
key.queryShape.singleBatch | 布尔 | $literal |
key.queryShape.max | 文档 | 标准化 |
key.queryShape.min | 文档 | 标准化 |
key.queryShape.returnKey | 布尔 | $literal |
key.queryShape.showRecordId | 布尔 | $literal |
key.queryShape.tailable | 布尔 | $literal |
key.queryShape.oplogReplay | 布尔 | $literal |
key.queryShape.awaitData | 布尔 | $literal |
key.queryShape.collation | 文档 | $literal |
key.queryShape.allowDiskUse | 布尔 | $literal |
key.queryShape.let | 文档 | 标准化 |
aggregate 命令查询结构
下表描述了aggregate
命令的查询结构属性。
字段 | 类型 | 字面值或规范化值 |
---|---|---|
key.queryShape.pipeline | 阵列 | 标准化 |
key.queryShape.explain | 布尔 | $literal |
key.queryShape.allowDiskUse | 布尔 | $literal |
key.queryShape.collation | 文档 | $literal |
key.queryShape.hint | 字符串或文档 | 标准化 |
key.queryShape.let | 文档 | 标准化 |
distinct 命令查询结构
下表描述了distinct
命令的查询结构属性。
字段 | 类型 | 字面值或规范化值 |
---|---|---|
key.queryShape.key | 字符串 | $literal |
key.queryShape.collation | 文档 | 标准化 |
key.queryShape.query | 文档 | 标准化 |
示例
要运行本节中的示例,请从以下数据开始:
db.products.insertMany( [ { item: "card", qty: 15 }, { item: "envelope", qty: 20 }, { item: "stamps" , qty: 30 } ] )
然后,运行以下命令:
db.products.find( { item: "card" } ) db.products.aggregate( [ { $match: { qty: { $gt: 20 } } } ] )
以下示例展示了使用不同类型的数据转换时$queryStats
的输出:
未转换示例
输入:
db.getSiblingDB("admin").aggregate( [ { $queryStats: { } } ] )
输出:
[ { 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=', 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") }, 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=', 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") }, firstSeenTimestamp: ISODate("2023-11-29T21:16:17.796Z"), latestSeenTimestamp: ISODate("2023-11-29T21:17:12.385Z") }, asOf: Timestamp({ t: 1701292827, i: 0 }) } ]
转换后的示例
输入:
db.getSiblingDB("admin").aggregate( [ { $queryStats: { transformIdentifiers: { algorithm: "hmac-sha-256" , hmacKey: BinData(8, "87c4082f169d3fef0eef34dc8e23458cbb457c3sf3n2") } } } ] )
输出:
[ { 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=', 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: false, usedDisk: false, fromMultiPlanner: false, fromPlanCache: true, 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") }, 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=', 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: false, usedDisk: false, fromMultiPlanner: false, fromPlanCache: true, 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") }, firstSeenTimestamp: ISODate("2023-11-29T21:16:17.796Z"), latestSeenTimestamp: ISODate("2023-11-29T21:17:12.385Z") }, asOf: Timestamp({ t: 1701293302, i: 0 }) }, ]
MongoDB Atlas collection
MongoDB Atlas 定期使用$queryStats
收集有关查询的匿名数据,这有助于改进 MongoDB 产品。 您的数据还可能用于根据使用情况提出功能建议。 MongoDB 将通过$queryStats
收集的数据保留四年。
当 Atlas 在部署上运行$queryStats
时,它会为每个 Atlas 组织使用唯一的 HMAC 密钥来转换您的数据并避免收集敏感信息。