How can I query a specific month in mongodb, not date range, I need month to make a list of customer birthday for current month.
In SQL will be something like that:
SELECT * FROM customer WHERE MONTH(bday)='09'
Now I need to translate that in mongodb. Note: My dates are already saved in MongoDate type, I used this thinking that will be easy to work before but now I can't find easily how to do this simple thing.
With MongoDB 3.6 and newer, you can use the $expr
operator in your find()
query. This allows you to build query expressions that compare fields from the same document in a $match
stage.
db.customer.find({ "$expr": { "$eq": [{ "$month": "$bday" }, 9] } })
For other MongoDB versions, consider running an aggregation pipeline that uses the $redact
operator as it allows you to incorporate with a single pipeline, a functionality with $project
to create a field that represents the month of a date field and $match
to filter the documents
which match the given condition of the month being September.
In the above, $redact
uses $cond
tenary operator as means to provide the conditional expression that will create the system variable which does the redaction. The logical expression in $cond
will check
for an equality of a date operator field with a given value, if that matches then $redact
will return the documents using the $$KEEP
system variable and discards otherwise using $$PRUNE
.
Running the following pipeline should give you the desired result:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$eq": [{ "$month": "$bday" }, 9] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
This is similar to a $project
+$match
combo but you'd need to then select all the rest of the fields that go into the pipeline:
db.customer.aggregate([
{ "$match": { "bday": { "$exists": true } } },
{
"$project": {
"month": { "$month": "$bday" },
"bday": 1,
"field1": 1,
"field2": 1,
.....
}
},
{ "$match": { "month": 9 } }
])
With another alternative, albeit slow query, using the find()
method with $where
as:
db.customer.find({ "$where": "this.bday.getMonth() === 8" })