8.0版本新增。
为了防止某个操作造成过多的工作负载,可以暂时拒绝与此查询结构相关联的所有操作。为此,请使用 setQuerySettings 将此操作查询结构的 reject 字段设置为 true。被拒绝的查询结构也称为操作拒绝过滤器。
在查询规划期间,查询优化器使用查询设置作为附加输入,这样会影响为运行查询而选择的计划。
此页面上的步骤将创建一个示例集合,并使用操作拒绝过滤器阻止查询结构。
关于此任务
假设由于应用程序的一个查询效率低下,导致集群出现过多的工作负载。为了防止查询消耗过多的集群资源,请使用操作拒绝过滤器阻止此查询和类似的查询运行。
开始之前
要识别效率低下的查询,请使用以下方法,包括:
注意
您无法在Atlas免费或 Flex 集群上设立操作拒绝过滤。
步骤
创建示例集合
运行:
// 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" ) } ] )
添加操作拒绝过滤器
运行如下 setQuerySettings 命令,以添加带有以下字段的操作拒绝过滤器:
find带有一个过滤器和一个排序,定义了查询结构。$db数据库(为查询设置)。settings拒绝查询结构。
db.adminCommand( { setQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" }, settings: { reject: true } } )
截断的如下输出显示了 queryShapeHash 字段值,settings reject 字段为 true:
{ queryShapeHash: 'AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1', settings: { reject: true }, representativeQuery: { find: 'pizzaOrders', filter: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, sort: { totalNumber: 1 }, '$db': 'test' }, ok: 1, ... }
(可选)使用解释命令确认设置
运行 explain:
db.pizzaOrders.explain().find( { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
截断的如下输出表明,querySettings reject 字段为 true:
{ queryPlanner: { winningPlan: { stage: 'SINGLE_SHARD', shards: [ { explainVersion: '1', ... namespace: 'test.pizzaOrders', parsedQuery: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, querySettings: { reject: true }, ... } ] } }
(可选)列出所有操作拒绝筛选器
要列出所有操作拒绝筛选器,请在聚合中使用$querySettings 和$match 阶段。在以下聚合示例中:
showDebugQueryShape字段在 阶段为true$querySettings,此阶段会返回查询结构的调试版本。有关详细信息,请参阅查询结构统计信息。$match阶段筛选查询设置以保留将settings.reject设立为true的设置,这对应于操作拒绝筛选器。
聚合示例:
db.aggregate( [ { $querySettings: { showDebugQueryShape: true } }, { $match: { "settings.reject": true } } ] )
输出:
[ { queryShapeHash: 'AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1', settings: { reject: true }, representativeQuery: { find: 'pizzaOrders', filter: { orderDate: { '$gt': ISODate('2023-01-20T00:00:00.000Z') } }, sort: { totalNumber: 1 }, '$db': 'test' }, debugQueryShape: { cmdNs: { db: 'test', coll: 'pizzaOrders' }, command: 'find', filter: { orderDate: { '$gt': '?date' } }, sort: { totalNumber: 1 } } } ]
(可选)删除操作拒绝过滤器
如下示例使用 removeQuerySettings 删除操作拒绝过滤器,此过滤器由前面的第 2 步中所示的输出中的 queryShapeHash 值识别:
db.adminCommand( { removeQuerySettings: "AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1" } )
也可以从以下位置获取 queryShapeHash 值:
也可以使用查询结构删除操作拒绝过滤器。例如:
db.adminCommand( { removeQuerySettings: { find: "pizzaOrders", filter: { orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) } }, sort: { totalNumber: 1 }, $db: "test" } } )
后续步骤
使用操作拒绝过滤器阻止低效操作之后,集群性能应当恢复到引入低效查询之前的状态。后续步骤:
解决查询性能问题。这可能需要执行索引或重写查询。
部署更新后的应用程序。
要重新启用未删除的查询设置,请使用 setQuerySettings 并将 reject 字段设置为 false。