To enhance your query performance, you can utilize aggregation with $facet to execute both queries simultaneously followed by a calculation using $subtract
. Here's an example:
db.collection.aggregate([
{$facet:{
total:[
{$match: {"createdBy._id": ObjectId("5e9dac4699a7bb0007e33460")}},
{$count: "count"}
],
constrained:[
{$match:{
"createdBy._id": ObjectId("5e9dac4699a7bb0007e33460"),
$or:[
{"data.questions.stimulus" : /\\\\\w+/},
{"data.questions.options.label" : /\\\\\w+/},
{"data.questions.validation.validResponse.value" : /\\\\\w+/},
{"data.questions.validation.altResponses.value": /\\\\\w+/},
{"data.questions.hints.label": /\\\\\w+/}
]
}},
{$count: "count"}
]
}},
{$addFields: {
total:{$arrayElemAt:["$total",0]},
constrained:{$arrayElemAt:["$constrained",0]}
}},
{$addFields:{
difference:{
$subtract:[
"$total.count",
"$constrained.count"
]
}
}}
])
An alternative approach would be to leverage $group as shown below:
db.collection.aggregate([
{$match: {"createdBy._id": ObjectId("5e9dac4699a7bb0007e33460")}},
{$group: {
_id:"$createdBy._id",
total:{$sum:1},
constrained:{
$sum:{
$cond:{
if:{
$or:[
{$regexMatch:{
input:"$data.questions.stimulus",
regex: /\\\\\w+/}},
{$regexMatch:{
input:"$data.questions.options.label",
regex: /\\\\\w+/}},
{$regexMatch:{
input:"$data.questions.validation.validResponse.value",
regex:/\\\\\w+/}},
{$regexMatch:{
input:"$data.questions.validation.altResponses.value",
regex: /\\\\\w+/}},
{$regexMatch:{
input:"$data.questions.hints.label",
regex: /\\\\\w+/}}
]
},
then:1,
else:0
}
}
}
}},
{$addFields:{difference:{$subtract:["$total","$constrained"]}}}
])