MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

MongoDB nombre total de retours de 0 si aucun document

Avis de non-responsabilité :je ne recommande pas de le faire côté serveur (donc à l'intérieur de MongoDB), mais plutôt de gérer ce cas côté client.

Cela dit, voici une solution générique à votre problème qui devrait être facilement adaptable à votre cas spécifique.

Imaginez que vous ayez les documents suivants (ou la sortie d'un pipeline d'agrégation comme dans votre exemple) :

{
    "category" : 1
}
{
    "category" : 1
}
// note the missing { category: 2 } document here
{
    "category" : 3
}

Le pipeline suivant créera des buckets vides (donc des documents avec un nombre de 0 pour les valeurs "gap" qui manquent dans la plage de valeurs de la category champ - dans ce cas le chiffre 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
                ]
            }
        }
    }
})

Le résultat de la requête ci-dessus sera :

{
    "_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
}