定义
8.0版本新增。
setQuerySettings 定义 find、distinct 和 aggregate 命令使用的查询设置。
您可以使用查询设置添加索引提示,定义操作拒绝筛选器,并为集群上给定查询结构的所有执行设立其他字段。集群的查询设置在重启后仍然存在。
查询优化器在查询规划期间使用查询设置作为附加input。查询设置中的索引提示会限制规划器可用的索引设立,但不保证规划器一定会使用索引。规划器仍然可以选择集合扫描作为给定查询结构哈希的获胜计划。
集群查询设置优先于作为命令字段传递的查询设置或索引提示。如果匹配的查询设置已包含索引提示,MongoDB将忽略命令字段中的索引提示。
索引提示不会影响查询结构。
For more information about hints and query settings, see Query Settings Syntax.
注意
要删除查询设置,请使用removeQuerySettings。要查看当前查询设置,请使用聚合管道中的 $querySettings 阶段。
查询设置和索引过滤器
从MongoDB 8.0 开始,索引过滤器已弃用。请改用查询设置。
查询设置的功能比索引过滤器更多。索引过滤器不是持久性的,您无法轻松地为所有集群节点创建索引过滤器。
语法
可以使用这一部分中所示的两种语法规范之一添加或更新查询设置。
通过传入查询来设置查询设置
在如下语法中,您需要提供:
一个
$db字段,用于为查询设置指定数据库。带有
indexHints和其他字段的settings文档。
db.adminCommand( { setQuerySettings: { <fields>, // Provide fields for // find, distinct, or aggregate command $db: <string> // Provide a database name }, // Provide a settings document with indexHints and other fields settings: { indexHints: [ { ns: { db: <string>, coll: <string> }, allowedIndexes: <array> }, ... ], queryFramework: <string>, reject: <boolean>, comment: <BSON type> } } )
传入查询结构哈希,以设置查询设置
可以在 setQuerySettings 中提供现有的查询结构哈希字符串,以及包含 indexHints 和其他字段的更新后的 settings 文档:
db.adminCommand( { setQuerySettings: <string>, // Provide an existing query shape hash string // Provide a settings document with indexHints and other fields settings: { indexHints: [ { ns: { db: <string>, coll: <string> }, allowedIndexes: <array> }, ... ], queryFramework: <string>, reject: <boolean>, comment: <BSON type> } } )
查询结构哈希是一个唯一标识查询结构的字符串。查询结构哈希的一个示例是 "F42757F1AEB68B4C5A6DE6182B29B01947C829C926BCC01226BDA4DDE799766C"。
In current supported versions, the same query shape is expected to produce the same query shape hash across nodes and deployment types. To learn how the hash behaves across nodes, deployment types, and clusters, see Query Shape Hash Stability.
要获取查询结构哈希字符串,请执行以下任一操作:
在一个聚合管道中使用一个
$querySettings阶段,并检查queryShapeHash字段。检查数据库分析器输出。
查看慢查询日志。
如果使用哈希字符串设置查询设置,$querySettings聚合阶段输出中不会有 representativeQuery 字段。
提示
在这两种语法变体中,您都可以提供一个 indexHints 文档数组。如果只提供一个 indexHints 文档,可以省略数组括号。
命令字段
该命令使用以下字段:
字段 | 字段类型 | 必要性 | 说明 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| 文档或字符串 | 必需 | |||||||||
| 文档 | Optional | 索引提示的命名空间。只在指定了可选索引提示时需要。
| ||||||||
| 阵列 | Optional | |||||||||
| 字符串 | Optional | 可以将查询框架字符串设置为:
| ||||||||
| 布尔 | Optional | 如果为
默认值为 要启用一个查询结构,请为此查询结构再次运行
| ||||||||
| BSON 类型 | Optional | 评论可以是任何有效的BSON类型。示例:字符串、对象等。 您可以使用注释提供有关查询设置的其他信息。 示例,要添加一个字符串来说明添加查询设置的原因,请使用 要更新评论,请再次运行 您无法删除注释,但可以将其设立为带有空格字符的字符串。 您可以使用 注释显示在 从 MongoDB 8.0.4开始提供。 |
示例
以下示例创建一个集合并为不同命令添加查询设置。对于集群上查询结构的所有执行,这些示例将查询规划器限制为使用提示索引或集合扫描。
创建示例集合和索引
运行:
// Create pizzaOrders collection db.pizzaOrders.insertMany( [ { _id: 0, type: "pepperoni", size: "small", price: 19, totalNumber: 10, orderDate: ISODate( "2023-03-13T08:14:30Z" ) }, { _id: 1, type: "pepperoni", size: "medium", price: 20, totalNumber: 20, orderDate: ISODate( "2023-03-13T09:13:24Z" ) }, { _id: 2, type: "pepperoni", size: "large", price: 21, totalNumber: 30, orderDate: ISODate( "2023-03-17T09:22:12Z" ) }, { _id: 3, type: "cheese", size: "small", price: 12, totalNumber: 15, orderDate: ISODate( "2023-03-13T11:21:39.736Z" ) }, { _id: 4, type: "cheese", size: "medium", price: 13, totalNumber: 50, orderDate: ISODate( "2024-01-12T21:23:13.331Z" ) }, { _id: 5, type: "cheese", size: "large", price: 14, totalNumber: 10, orderDate: ISODate( "2024-01-12T05:08:13Z" ) }, { _id: 6, type: "vegan", size: "small", price: 17, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:08:13Z" ) }, { _id: 7, type: "vegan", size: "medium", price: 18, totalNumber: 10, orderDate: ISODate( "2023-01-13T05:10:13Z" ) } ] ) // Create ascending index on orderDate field db.pizzaOrders.createIndex( { orderDate: 1 } ) // Create ascending index on totalNumber field db.pizzaOrders.createIndex( { totalNumber: 1 } )
索引的默认名称为 orderDate_1 和 totalNumber_1。
为 find 命令添加查询设置
如下示例将为 find 命令添加查询设置。此示例将为 find 命令提供 setQuerySettings 中的字段,并包含 allowedIndexes 中的 orderDate_1 索引。
db.adminCommand( { setQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" }, settings: { indexHints: { ns: { db: "test", coll: "pizzaOrders" }, allowedIndexes: [ "orderDate_1" ] }, queryFramework: "classic", comment: "Index hint for orderDate_1 index to improve query performance" } } )
(可选)验证查询设置
运行此 explain 命令:
db.pizzaOrders.explain().find( { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
截断的如下输出显示了所设定的查询设置:
queryPlanner: { winningPlan: { stage: 'SINGLE_SHARD', shards: [ { explainVersion: '1', ... namespace: 'test.pizzaOrders', indexFilterSet: false, parsedQuery: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, querySettings: { indexHints: { ns: { db: 'test', coll: 'pizzaOrders' }, allowedIndexes: [ 'orderDate_1' ] }, queryFramework: 'classic', comment: 'Index hint for orderDate_1 index to improve query performance' }, ... } ... ] } }
(可选)运行查询
如下示例将运行查询:
db.pizzaOrders.find( { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
在查询规划期间,查询优化器使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。
查询输出:
[ { _id: 0, type: 'pepperoni', size: 'small', price: 19, totalNumber: 10, orderDate: ISODate('2023-03-13T08:14:30.000Z') }, { _id: 5, type: 'cheese', size: 'large', price: 14, totalNumber: 10, orderDate: ISODate('2024-01-12T05:08:13.000Z') }, { _id: 3, type: 'cheese', size: 'small', price: 12, totalNumber: 15, orderDate: ISODate('2023-03-13T11:21:39.736Z') }, { _id: 1, type: 'pepperoni', size: 'medium', price: 20, totalNumber: 20, orderDate: ISODate('2023-03-13T09:13:24.000Z') }, { _id: 2, type: 'pepperoni', size: 'large', price: 21, totalNumber: 30, orderDate: ISODate('2023-03-17T09:22:12.000Z') }, { _id: 4, type: 'cheese', size: 'medium', price: 13, totalNumber: 50, orderDate: ISODate('2024-01-12T21:23:13.331Z') } ]
(可选)获取查询设置
如下示例使用一个聚合管道中的 $querySettings 阶段获取查询设置:
db.aggregate( [ { $querySettings: {} } ] )
截断后的输出,包括 queryShapeHash 字段:
[ { queryShapeHash: 'AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1', settings: { indexHints: [ { ns: { db: 'test', coll: 'pizzaOrders' }, allowedIndexes: [ 'orderDate_1' ] } ], queryFramework: 'classic', comment: 'Index hint for orderDate_1 index to improve query performance' }, representativeQuery: { find: 'pizzaOrders', filter: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, sort: { totalNumber: 1 }, '$db': 'test' } } ]
为不同的命令添加查询设置
如下示例将为 distinct 命令添加查询设置:
db.adminCommand( { setQuerySettings: { distinct: "pizzaOrders", key: "totalNumber", query: { totalNumber: 10, orderDate :{ '$gt': ISODate('2023-01-20T00:00:00.000Z') } } , $db: "test" }, settings: { indexHints: { ns: { db: "test", coll: "pizzaOrders" }, allowedIndexes: [ "orderDate_1" ] }, queryFramework: "classic", comment: "Index hint for orderDate_1 index to improve query performance" } } )
为聚合命令添加查询设置
如下示例将为 aggregate 命令添加查询设置:
db.adminCommand( { setQuerySettings: { aggregate: "pizzaOrders", pipeline: [ { $match: { totalNumber: 10, orderDate :{ '$gt': ISODate('2023-01-20T00:00:00.000Z') } } }, { $group: { _id: "$type", totalMediumPizzaOrdersGroupedByType: { $sum: "$totalNumber" } } } ], $db: "test" }, settings: { indexHints: { ns: { db: "test", coll: "pizzaOrders" }, allowedIndexes: [ "totalNumber_1" ] }, queryFramework: "classic", comment: "Index hint for totalNumber_1 index to improve query performance" } } )