Come ottenere tutto il conteggio del modello di mangusta?


101

Come posso sapere il conteggio di un modello di cui sono stati salvati i dati? c'è un metodo di Model.count(), ma non sembra funzionare.

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');

userCountè un oggetto, quale metodo chiamato può ottenere un vero count?

Grazie


1
Se stai usando ES 2016, puoi racchiudere la chiamata per contare all'interno di una promessa e chiamarla con un generatore.
mikeyGlitz

Risposte:


125

Il codice seguente funziona. Nota l'uso di 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

Il motivo per cui il codice non funziona è perché la funzione di conteggio è asincrona, non restituisce un valore in modo sincrono.

Ecco un esempio di utilizzo:

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

Dammi un esempio per ottenere il metodo di conteggio sincrono
sankar muniyappa,

Stessa cosa per me. Sto cercando lo stesso
nowox

11
countè deprecato, puoi usare la countDocumentsstessa sintassi
Kir Novak

@KirNovak Grazie fratello. Ho anche fornito l'URL in mangusta per la deprecazione .
Tes3awy

25

Collection.count è deprecato e verrà rimosso in una versione futura. Usa raccolta. countDocuments o collezione. stimatoDocumentCount invece.

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

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


Ho avuto il problema che nel nostro progetto una routine di configurazione verifica gli elementi esistenti in qualsiasi collezione. Il metodo count () si comportava in modo strano: quando la raccolta non era vuota, a volte non restituiva nulla (undefined, null, zero o false - non potevamo indagare ulteriormente). Non abbiamo ancora scoperto cosa abbia causato il problema poiché si trattava di una condizione di gara che si verificava molto raramente. L'utilizzo di countDocuments ({}) ora funziona per noi. Grazie!
ha110_b1mm3lbahn

UnhandledPromiseRejectionWarning: TypeError: userModel.countDocuments is not a functionRicevo un errore quando lo utilizzo sul mio userModel?
Luke Brown

Come possiamo rendere "userModel.countDocuments" come chiamata sincrona in modo da poter aggiungere un virtuale allo schema che aggiunge qualche "chiave e valore" nel mio documento.
Satyam

25

Dovresti dare un oggetto come argomento

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

o

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

o

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

Nella versione recente di mongoose, count () è deprecato, quindi usa

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

2
DeprecationWarning: collection.count è deprecato, dovresti invece usare .estimatedDocumentCount () o .countDocuments ().
HMagdy

9

Sfondo per la soluzione

Come affermato nella documentazione di mongoose e nella risposta di Benjamin, il metodo Model.count()è deprecato. Invece di utilizzare count(), le alternative sono le seguenti:

Model.countDocuments(filterObject, callback)

Conta quanti documenti corrispondono al filtro in una raccolta. Il passaggio di un oggetto vuoto {} come filtro esegue una scansione completa della raccolta. Se la raccolta è grande, potrebbe essere utilizzato il seguente metodo.

Model.estimatedDocumentCount()

Questo metodo modello stima il numero di documenti nella raccolta MongoDB. Questo metodo è più veloce del precedente countDocuments(), perché utilizza i metadati della raccolta invece di passare attraverso l'intera raccolta. Tuttavia, come suggerisce il nome del metodo e in base alla configurazione del database, il risultato è una stima poiché i metadati potrebbero non riflettere il conteggio effettivo dei documenti in una raccolta al momento dell'esecuzione del metodo.

Entrambi i metodi restituiscono un oggetto query mongoose, che può essere eseguito in uno dei due modi seguenti. Utilizzare .exec()se si desidera eseguire una query in un secondo momento.

La soluzione

Opzione 1: passare una funzione di callback

Ad esempio, conta tutti i documenti in una raccolta utilizzando .countDocuments():

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

In alternativa, conta tutti i documenti in una raccolta con un determinato nome utilizzando .countDocuments():

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

Opzione 2: utilizzare .then()

Una query mangusta ha .then() quindi è "quindi modificabile". Questo è per comodità e la query in sé non è una promessa.

Ad esempio, conta tutti i documenti in una raccolta utilizzando .estimatedDocumentCount():

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

Opzione 3: usa async / await

Quando si usa l'approccio async / await, il modo consigliato è usarlo con .exec()in quanto fornisce migliori tracce dello stack.

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

Imparando da stackoverflow,


1

Le risposte con il voto più alto qui vanno perfettamente bene, voglio solo sommare l'uso di await in modo che la funzionalità richiesta possa essere archiviata:

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

Si consiglia di usare countDocuments () su 'count ()' poiché sarà deprecato in corso. Quindi, per ora, il codice perfetto sarebbe:

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

-1

Come detto prima, il codice non funzionerà nel modo in cui è. Una soluzione a questo sarebbe utilizzare una funzione di callback, ma se pensi che ti porterebbe a un "inferno di richiamata", puoi cercare "Promisses".

Una possibile soluzione utilizzando una funzione di callback:

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

se vuoi cercare il numero di documenti in base a una query, puoi farlo:

 userModel.count({yourQueryGoesHere}, setNumberofDocuments);

setNumberofDocuments è una funzione separata:

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

        numberofDocs = count;

      };

Ora puoi ottenere il numero di documenti ovunque con getFunction:

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

Inoltre, si utilizza questa funzione asincrona all'interno di una sincrona utilizzando un callback, ad esempio:

function calculateNumberOfDoc(someParameter, setNumberofDocuments){

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

       setNumberofDocuments(true);


} 

Spero che possa aiutare gli altri. :)


Nella funzione calcolareNumberOfDoc (), perché stai chiamando setNumberofDocuments (true)? Non si verificherebbe prima un errore, anche prima che venga restituito il conteggio effettivo?
pravin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.