Docs Menu
Docs Home
/
MongoDB Manual
/ / / /

Block Slow Queries with Operation Rejection Filters

On this page

  • About this Task
  • Before you Begin
  • Steps
  • Next Steps
  • Learn More

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.

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.

To identify an inefficient query, use various methods that include:

  • Atlas monitoring

  • Atlas alerts

  • Atlas Query Profiler

  • Slow query logs

1

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" ) }
] )
2

Run the following setQuerySettings command to add an operation rejection filter with these fields:

  • find with a filter and a sort, which defines the query shape.

  • $db with the database for the query settings.

  • settings that 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

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

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

The following example uses removeQuerySettings to remove the operation rejection filter, which are identified using the queryShapeHash value from the output shown in step 2 earlier:

db.adminCommand( {
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"
}
} )
6

Because the operation rejection filter is removed, the following query is unblocked and now runs:

db.pizzaOrders.find( { orderDate: {
$gt: ISODate("2023-01-20T00:00:00Z" ) } } ).sort( { totalNumber: 1 } )

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:

  1. Resolve the performance problem with the query. This may require an index or a query rewrite.

  2. Deploy the updated application.

To re-enable query settings that aren't deleted, use setQuerySettings and set the reject field to false.

Back

Output