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


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

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

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


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"});

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,


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

-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. :)


Dlaczego w funkcji calculatorNumberOfDoc () wywołujesz metodę setNumberofDocuments (true)? Czy nie spowodowałoby to najpierw błędu, nawet przed zwróceniem rzeczywistej liczby?
pravin
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.