I am currently trying to optimize some queries by using aggregation pipelines. Now I want to have a $match stage that filters out most of the collection documents in order to speed up the following stages. The problem I am facing is that the documents in the collection do contain fields that represent regular expressions. I now want to match strings against these regular expressions (preferably in the first $match stage).
This is how my current solution looks. But I am not really happy with this in terms of readability and probably performance.
[
{$match: {
name: "docName"
}
},
{$addFields: {
fieldAMatches: {$regexMatch: {input: "ABC", regex: '$fieldA'
}
}
}
},
{$match: {
fieldAMatches: true
}
}
]
A sample dataset would look the following:
[
{
"_id": 1,
"name": "docName",
"fieldA": ".*"
},
{
"_id": 2,
"name": "docName",
"fieldA": "AB.*"
},
{
"_id": 3,
"name": "docName",
"fieldA": "AB.+"
},
{
"_id": 4,
"name": "docName",
"fieldA": "BAC"
}
]
The result contains the following documents:
[
{
"_id": 1,
"name": "docName",
"fieldA": ".*"
},
{
"_id": 2,
"name": "docName",
"fieldA": "AB.*"
},
{
"_id": 3,
"name": "docName",
"fieldA": "AB.+"
},
]
You can use $expr do achieve this, from the docs:
$match takes a document that specifies the query conditions. The query syntax is identical to the read operation query syntax; i.e. $match does not accept raw aggregation expressions. Instead, use a $expr query expression to include aggregation expression in $match.
Meaning by using $expr we can include aggregation expression (and in our case $regexMatch) in $match stage like so:
db.collection.aggregate([
{
$match: {
name: "docName",
$expr: {
$regexMatch: {
input: "ABC",
regex: "$fieldA"
}
}
}
}
])
Mongo Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With