Peguei sozinho:
db.bills.aggregate([
{
$match: {
$expr: {
$or: [
{
$and: [
{$eq: ["$year", FROMYEAR]},
{$eq: ["$year", TOYEAR]},
{$gte: ["$month", FROMMONTH},
{$lte: ["$month", TOMONTH},
]
},
{
$and: [
{$eq: ["$year", FROMYEAR]},
{$lt: ["$year", TOYEAR]},
{$gte: ["$month", FROMMONTH]}
]
},
{
$and: [
{$gt: ["$year", FROMYEAR]},
{$eq: ["$year", TOYEAR]},
{$lte: ["$month", TOMONTH]}
]
},
{
$and: [
{$gt: ["$year", FROMYEAR]},
{$lt: ["$year", TOYEAR]}
]
}
]
}
}
},
{
$project: {
"id": 1,
"month": 1,
"year": 1,
"_id": 0
}
},
,
{
$sort: {
"year": 1,
"month": 1
}
}
]).toArray()
A primeira é extrair fromYear, fromMonth, toYear, toMonth da consulta. O próximo é defini-lo para a posição correspondente na consulta. Existem 4 intervalos para corresponder:
MinYear = $year = MaxYear ==========> MinMonth < $month < MaxMonth
MinYear = $year < MaxYear ==========> MinMonth <= $month
MinYear < $year = MaxYear ==========> $month <= MaxMonth
MinYear < $year < MaxYear ==========> any $month
O resultado se parece com o seguinte:
[
{
"id" : "BI_0010",
"month" : 5,
"year" : 2017
},
{
"id" : "BI_0008",
"month" : 3,
"year" : 2018
},
{
"id" : "BI_0001",
"month" : 8,
"year" : 2018
}
]