New in version 8.0.
To prevent an operation from causing excessive workload, you can temporarily reject all operations associated with that query shape. To do that, use setQuerySettings to set the reject field to true for the operation's query shape. A rejected query shape is also known as an operation rejection filter.
The query optimizer uses the query settings as an additional input during query planning, which affects the plan selected to run the query.
The steps on this page create an example collection and use an operation rejection filter to block a query shape.
About this Task
Assume a cluster has excessive workload because an application has an inefficient query. To prevent the query from consuming excessive cluster resources, use an operation rejection filter to block the query and similar queries from running.
Before you Begin
To identify an inefficient query, use various methods that include:
Note
You can't set an operation rejection filter on Atlas M0 or Flex clusters.
Steps
Create the example collection
Run:
// 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" ) }
] )Add an operation rejection filter
Run the following setQuerySettings command to add an operation rejection filter with these fields:
findwith a filter and a sort, which defines the query shape.$dbwith the database for the query settings.settingsthat reject the query shape.
db.adminCommand( {
setQuerySettings: {
find: "pizzaOrders",
filter: {
orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) }
},
sort: {
totalNumber: 1
},
$db: "test"
},
settings: {
reject: true
}
} )The following truncated output shows the queryShapeHash field value and the settings reject field is 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,
...
}3
(Optional) Use the explain command to confirm settings
Run explain:
db.pizzaOrders.explain().find( { orderDate: { $gt: ISODate(
"2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
The following truncated output shows the querySettings reject
field is 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 },
...
}
]
}
}4
(Optional) Verify the query is rejected
Attempt to run this query:
db.pizzaOrders.find( { orderDate: {
$gt: ISODate("2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )
The following output verifies the query is rejected:
MongoServerError: Query rejected by admin query settings
5
(Optional) List all operation rejection filters
To list all of the operation rejection filters, use the $querySettings and $match stages in an aggregation. In the following aggregation example:
- The
showDebugQueryShape field is true in the $querySettings stage, which returns a debug version of the query shape. For details, see query shape statistics.
- The
$match stage filters the query settings to keep those where settings.reject is set to true, which corresponds to the operation rejection filters.
Aggregation example:
db.aggregate( [
{ $querySettings: { showDebugQueryShape: true } },
{ $match: { "settings.reject": true } }
] )
Output:
[
{
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: "AB8ECADEE8F0EB0F447A30744EB4813AE7E0BFEF523B0870CA10FCBC87F5D8F1"
} )You can also get the queryShapeHash value from:
You can also remove an operation rejection filter using a query shape. For example:
db.adminCommand( {
removeQuerySettings: {
find: "pizzaOrders",
filter: {
orderDate: { $gt: ISODate( "2023-01-20T00:00:00Z" ) }
},
sort: {
totalNumber: 1
},
$db: "test"
}
} )
7
Next Steps
After you block an inefficient operation using an operation rejection filter, your cluster performance should return to how it was before the inefficient query was introduced. Next steps:
- Resolve the performance problem with the query. This may require an index or a query rewrite.
- Deploy the updated application.
To re-enable query settings that aren't deleted, use setQuerySettings and set the reject field to false.
Learn More