Jak obliczyć wszystkie modele mangusty?

101

Skąd mogę wiedzieć, ile modeli zostało zapisanych? jest metoda Model.count(), ale wydaje się, że nie działa.

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

userCountjest obiektem, która wywołana metoda może uzyskać wartość rzeczywistą count?

Dzięki

smilexu
źródło
1
Jeśli używasz ES 2016, możesz zawinąć połączenie, aby liczyć wewnątrz obietnicy i wywołać je za pomocą generatora.
mikeyGlitz

Odpowiedzi:

125

Poniższy kod działa. Zwróć uwagę na użycie 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);
      });
   }
 }); 
almypal
źródło
150

Kod nie działa, ponieważ funkcja count jest asynchroniczna i nie zwraca synchronicznie wartości.

Oto przykład użycia:

userModel.count({}, function( err, count){
    console.log( "Number of users:", count );
})
UpTheCreek
źródło
Podaj mi przykład, aby
obliczyć
Dla mnie to samo. Szukam tego samego
nowox
11
countmetoda jest pozbawiona funkcji, możesz użyć tej countDocumentssamej składni
Kir Novak
@KirNovak Dzięki bracie. Podałem również adres URL w języku mongoose na potrzeby wycofania .
Tes3awy,
25

Collection.count jest przestarzała i zostanie usunięta w przyszłej wersji. Użyj kolekcji. countDocuments lub collection. Zamiast tego oszacowanoDocumentCount .

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

    res.json({ count: count });
});
Benzoes
źródło
3
tutaj jest link do dokumentacji: mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount
babar78
Miałem problem, że w naszym projekcie instalacja rutynowo testuje istniejące pozycje w dowolnych kolekcjach. Metoda count () zachowywała się dziwnie: gdy kolekcja nie była pusta, czasami nic nie zwracała (undefined, null, zero lub false - nie mogliśmy tego dalej zbadać). Nadal nie dowiedzieliśmy się, co spowodowało problem, ponieważ były to warunki wyścigu, które zdarzały się bardzo rzadko. Używanie countDocuments ({}) teraz działa dla nas. Dziękuję Ci!
ha110_b1mm3lbahn
UnhandledPromiseRejectionWarning: TypeError: userModel.countDocuments is not a functionWystępuje błąd podczas używania go na moim własnym modelu użytkownika?
Luke Brown
Jak możemy uczynić „userModel.countDocuments” jako wywołanie synchroniczne, abym mógł dodać wirtualny do schematu, który dodaje „klucz i wartość” w moim dokumencie.
Satyam
25

Jako argument należy podać obiekt

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

lub

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

lub

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

W najnowszej wersji mongoose funkcja count () jest przestarzała, więc użyj

userModel.countDocuments({name: "sam"});
Moh .S
źródło
2
DeprecationWarning: collection.count jest przestarzała, należy zamiast tego użyć .estimatedDocumentCount () lub .countDocuments ().
HMagdy
9

Tło rozwiązania

Jak stwierdzono w dokumentacji mangusty i w odpowiedzi Benjamina, metoda Model.count()jest przestarzała. Zamiast używać count(), alternatywy są następujące:

Model.countDocuments(filterObject, callback)

Oblicza, ile dokumentów pasuje do filtra w kolekcji. Przekazanie pustego obiektu {} jako filtru powoduje wykonanie pełnego skanowania kolekcji. Jeśli kolekcja jest duża, można użyć następującej metody.

Model.estimatedDocumentCount()

Ta metoda modelu szacuje liczbę dokumentów w kolekcji MongoDB. Ta metoda jest szybsza niż poprzednia countDocuments(), ponieważ używa metadanych kolekcji zamiast przechodzić przez całą kolekcję. Jednak, jak sugeruje nazwa metody, w zależności od konfiguracji bazy danych, wynikiem jest oszacowanie, ponieważ metadane mogą nie odzwierciedlać faktycznej liczby dokumentów w kolekcji w momencie wykonywania metody.

Obie metody zwracają obiekt zapytania mongoose, który można wykonać na jeden z dwóch poniższych sposobów. Użyj, .exec()jeśli chcesz wykonać zapytanie w późniejszym czasie.

Rozwiązanie

Opcja 1: Przekaż funkcję zwrotną

Na przykład policz wszystkie dokumenty w kolekcji, używając .countDocuments():

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

Lub policz wszystkie dokumenty w kolekcji o określonej nazwie, używając .countDocuments():

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

Opcja 2: Użyj .then()

Zapytanie .then()o mangustę ma, więc jest „możliwe”. To jest dla wygody, a samo zapytanie nie jest obietnicą.

Na przykład policz wszystkie dokumenty w kolekcji, używając .estimatedDocumentCount():

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

Opcja 3: użyj async / await

Korzystając z podejścia async / await, zalecanym sposobem jest użycie go z, .exec()ponieważ zapewnia lepsze ślady stosu.

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

Nauka przez przepełnienie stosu,

heilala
źródło
1

Najwyżej ocenione tutaj odpowiedzi są w porządku. Chcę tylko dodać użycie await, aby żądana funkcjonalność mogła zostać zarchiwizowana:

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

Zaleca się używanie funkcji countDocuments () zamiast funkcji „count ()”, ponieważ będzie ona przestarzała. Tak więc na razie idealny kod wyglądałby tak:

const documentCount = await userModel.countDocuments({});
console.log( "Number of users:", documentCount );
Mridul Tripathi
źródło
-1

Jak wspomniano wcześniej, kod nie będzie działał tak, jak jest. Rozwiązaniem tego problemu byłoby użycie funkcji zwrotnej, ale jeśli myślisz, że zaprowadzi Cię to do „piekła oddzwonienia”, możesz wyszukać „Promisses”.

Możliwe rozwiązanie wykorzystujące funkcję zwrotną:

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

jeśli chcesz wyszukać liczbę dokumentów na podstawie zapytania, możesz to zrobić:

 userModel.count({yourQueryGoesHere}, setNumberofDocuments);

setNumberofDocuments to oddzielna funkcja:

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

        numberofDocs = count;

      };

Teraz możesz uzyskać liczbę dokumentów w dowolnym miejscu dzięki funkcji getFunction:

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

Ponadto tej funkcji asynchronicznej używa się wewnątrz funkcji synchronicznej, używając wywołania zwrotnego, na przykład:

function calculateNumberOfDoc(someParameter, setNumberofDocuments){

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

       setNumberofDocuments(true);


} 

Mam nadzieję, że może pomóc innym. :)

AndBecaPine
źródło
Dlaczego w funkcji calculatorNumberOfDoc () wywołujesz metodę setNumberofDocuments (true)? Czy nie spowodowałoby to najpierw błędu, nawet przed zwróceniem rzeczywistej liczby?
pravin