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.