Disclaimer:ik raad niet aan om dit aan de serverzijde te doen (dus binnen MongoDB), maar behandel die zaak liever aan de clientzijde.
Dat gezegd hebbende, hier is een generieke oplossing voor uw probleem die gemakkelijk moet kunnen worden aangepast aan uw specifieke geval.
Stel je voor dat je de volgende documenten hebt (of uitvoer van een aggregatiepijplijn zoals in je voorbeeld):
{
"category" : 1
}
{
"category" : 1
}
// note the missing { category: 2 } document here
{
"category" : 3
}
De volgende pijplijn maakt lege buckets (dus documenten met een telling van 0 voor de "gap"-waarden die ontbreken in het waardenbereik in de category
veld - in dit geval het nummer 2):
var bucketSize = 1;
db.getCollection('test').aggregate({
$group: {
_id: null, // throw all documents into the same bucket
"min": { $min: "$category" }, // just to calculate the lowest
"max": { $max: "$category" }, // and the highest "category" value
"docs": { $push: "$$ROOT" } // and also keep the root documents
}
}, {
$addFields: {
"docs": { // modify the existing docs array - created in the previous stage
$concatArrays: [ // by concatenating
"$docs", // the existing docs array
{
$map: { // with some other array that will be generated
input: {
$range: [ "$min", "$max", bucketSize ] // based on the min and max values and the bucket size
},
as: "this",
in: { // but represented not as a plain number but as a document that effectively creates a bogus document
"category": "$$this", // the bogus category will be set to the respective value
"bogus": 1 // marker that allows us not to count this document in the next stage and still get a bucket from $group
}
}
}
]
}
}
}, {
$unwind: "$docs" // flatten the "docs" array which will now contain the bogus documents, too
}, {
$group: {
_id: "$docs.category", // group by category
"count": { // this is the result we are interested in
$sum: { // which will be aggregated by calculating the sum for each document of
$cond: [ // either 0 or 1 per document
{ $eq: [ "$docs.bogus", 1 ] }, // depending on whether the document should count as a result or not
0,
1
]
}
}
}
})
De uitvoer van de bovenstaande vraag is:
{
"_id" : 2,
"count" : 0.0 // this is what we wanted to achieve
}
{
"_id" : 3,
"count" : 1.0 // correct number of matches
}
{
"_id" : 1,
"count" : 2.0 // correct number of matches
}