Comment obtenir tout le nombre de modèles de mangouste?


101

Comment puis-je connaître le nombre de modèles dont les données ont été enregistrées? il existe une méthode Model.count(), mais cela ne semble pas fonctionner.

var db = mongoose.connect('mongodb://localhost/myApp');
var userSchema = new Schema({name:String,password:String});
userModel =db.model('UserList',userSchema);        
var userCount = userModel.count('name');

userCountest un objet, quelle méthode appelée peut obtenir un réel count?

Merci


1
Si vous utilisez ES 2016, vous pouvez encapsuler l'appel pour compter à l'intérieur d'une promesse et l'appeler avec un générateur.
mikeyGlitz

Réponses:


125

Le code ci-dessous fonctionne. Notez l'utilisation de countDocuments .

 var mongoose = require('mongoose');
 var db = mongoose.connect('mongodb://localhost/myApp');
 var userSchema = new mongoose.Schema({name:String,password:String});
 var userModel =db.model('userlists',userSchema);
 var anand = new userModel({ name: 'anand', password: 'abcd'});
 anand.save(function (err, docs) {
   if (err) {
       console.log('Error');
   } else {
       userModel.countDocuments({name: 'anand'}, function(err, c) {
           console.log('Count is ' + c);
      });
   }
 }); 

150

La raison pour laquelle votre code ne fonctionne pas est que la fonction de comptage est asynchrone, elle ne renvoie pas de valeur de manière synchrone.

Voici un exemple d'utilisation:

userModel.count({}, function( err, count){
    console.log( "Number of users:", count );
})

Donnez-moi un exemple pour obtenir la méthode synchrone de
comptage

Pareil pour moi. Je cherche la même chose
nowox

11
countméthode est obsolète, vous pouvez utiliser la countDocumentsmême syntaxe
Kir Novak

@KirNovak Merci mon frère. J'ai également fourni l'url en mangouste pour la dépréciation .
Tes3awy

25

Le collection.count est obsolète et sera supprimé dans une version ultérieure. Utilisez la collection. countDocuments ou collection. EstiméDocumentCount à la place.

userModel.countDocuments(query).exec((err, count) => {
    if (err) {
        res.send(err);
        return;
    }

    res.json({ count: count });
});


J'ai eu le problème, que dans notre projet un test de routine de configuration pour les éléments existants dans toutes les collections. La méthode count () s'est comportée de façon étrange: lorsque la collection n'était pas vide, elle ne renvoyait parfois rien (indéfini, nul, zéro ou faux - nous ne pouvions pas l'étudier plus avant). Nous n'avons toujours pas trouvé la cause du problème car c'était une condition de course qui se produisait très rarement. L'utilisation de countDocuments ({}) fonctionne désormais pour nous. Je vous remercie!
ha110_b1mm3lbahn

UnhandledPromiseRejectionWarning: TypeError: userModel.countDocuments is not a functionJ'obtiens une erreur lors de son utilisation sur mon propre userModel?
Luke Brown

Comment pouvons-nous faire "userModel.countDocuments" comme appel synchrone afin que je puisse ajouter un virtuel au schéma qui ajoute une certaine "clé et valeur" dans mon document.
Satyam

25

Vous devriez donner un objet comme argument

userModel.count({name: "sam"});

ou

userModel.count({name: "sam"}).exec(); //if you are using promise

ou

userModel.count({}); // if you want to get all counts irrespective of the fields

Sur la version récente de mongoose, count () est obsolète donc utilisez

userModel.countDocuments({name: "sam"});

2
DeprecationWarning: collection.count est obsolète, vous devez utiliser à la place .estimatedDocumentCount () ou .countDocuments ().
HMagdy

9

Contexte de la solution

Comme indiqué dans la documentation mangouste et dans la réponse de Benjamin, la méthode Model.count()est obsolète. À la place d'utilisercount() , les alternatives sont les suivantes:

Model.countDocuments(filterObject, callback)

Compte le nombre de documents correspondant au filtre dans une collection. Passer un objet vide {} comme filtre exécute une analyse complète de la collection. Si la collection est volumineuse, la méthode suivante peut être utilisée.

Model.estimatedDocumentCount()

Cette méthode de modèle estime le nombre de documents dans la collection MongoDB. Cette méthode est plus rapide que la précédente countDocuments(), car elle utilise les métadonnées de la collection au lieu de parcourir toute la collection. Cependant, comme le nom de la méthode l'indique et en fonction de la configuration de la base de données, le résultat est une estimation car les métadonnées peuvent ne pas refléter le nombre réel de documents dans une collection au moment de l'exécution de la méthode.

Les deux méthodes renvoient un objet de requête mangouste, qui peut être exécuté de l'une des deux manières suivantes. À utiliser .exec()si vous souhaitez exécuter une requête ultérieurement.

La solution

Option 1: passer une fonction de rappel

Par exemple, comptez tous les documents d'une collection en utilisant .countDocuments():

someModel.countDocuments({}, function(err, docCount) {
    if (err) { return handleError(err) } //handle possible errors
    console.log(docCount)
    //and do some other fancy stuff
})

Ou, comptez tous les documents d'une collection portant un certain nom en utilisant .countDocuments():

someModel.countDocuments({ name: 'Snow' }, function(err, docCount) {
    //see other example
}

Option 2: utilisation .then()

Une requête mangouste a .then() donc elle est «alorsable». Ceci est pour une commodité et la requête en elle-même n'est pas une promesse.

Par exemple, comptez tous les documents d'une collection en utilisant .estimatedDocumentCount():

someModel
    .estimatedDocumentCount()
    .then(docCount => {
        console.log(docCount)
        //and do one super neat trick
    })
    .catch(err => {
        //handle possible errors
    })

Option 3: utiliser async / await

Lorsque vous utilisez l'approche async / await, la méthode recommandée est de l'utiliser avec .exec()car elle fournit de meilleures traces de pile.

const docCount = await someModel.countDocuments({}).exec();

Apprendre par stackoverflowing,


1

Les réponses aux votes les plus élevés ici sont parfaitement bien.Je veux juste additionner l'utilisation de wait pour que la fonctionnalité demandée puisse être archivée:

const documentCount = await userModel.count({});
console.log( "Number of users:", documentCount );

Il est recommandé d'utiliser countDocuments () sur 'count ()' car il sera obsolète en cours. Donc, pour l'instant, le code parfait serait:

const documentCount = await userModel.countDocuments({});
console.log( "Number of users:", documentCount );

-1

Comme dit précédemment, votre code ne fonctionnera pas comme il est. Une solution à cela serait d'utiliser une fonction de rappel, mais si vous pensez que cela vous mènerait à un «enfer de rappel», vous pouvez rechercher «Promisses».

Une solution possible utilisant une fonction de rappel:

//DECLARE  numberofDocs OUT OF FUNCTIONS
     var  numberofDocs;
     userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection

si vous souhaitez rechercher le nombre de documents en fonction d'une requête, vous pouvez le faire:

 userModel.count({yourQueryGoesHere}, setNumberofDocuments);

setNumberofDocuments est une fonction séparée:

var setNumberofDocuments = function(err, count){ 
        if(err) return handleError(err);

        numberofDocs = count;

      };

Vous pouvez maintenant obtenir le nombre de documents n'importe où avec une fonction getFunction:

     function getNumberofDocs(){
           return numberofDocs;
        }
 var number = getNumberofDocs();

De plus, vous utilisez cette fonction asynchrone dans une fonction synchrone en utilisant un rappel, exemple:

function calculateNumberOfDoc(someParameter, setNumberofDocuments){

       userModel.count({}, setNumberofDocuments); //this search all DOcuments in a Collection

       setNumberofDocuments(true);


} 

J'espère que cela peut aider les autres. :)


Dans la fonction CalculateNumberOfDoc (), pourquoi appelez-vous setNumberofDocuments (true)? Cela n'entraînerait-il pas une erreur avant même que le décompte réel ne soit renvoyé
pravin
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.