Як отримати всі підрахунки мангустної моделі?


101

Як я можу дізнатися кількість моделей, які зберегли дані? існує метод Model.count(), але він, здається, не працює.

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є Об'єктом, який названий метод може отримати реальний count?

Дякую


1
Якщо ви використовуєте ES 2016, ви можете зафіксувати виклик для підрахунку обіцянки та викликати його генератором.
mikeyGlitz

Відповіді:


125

Код нижче працює. Зверніть увагу на використання 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

Причина, що ваш код не працює, полягає в тому, що функція підрахунку є асинхронною, вона не синхронно повертає значення.

Ось приклад використання:

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

Наведіть мені приклад для підрахунку синхронного способу
sankar muniyappa

Те саме для мене. Шукаю те саме
nowox

11
countметод оприлюднений, ви можете використовувати countDocumentsтой же синтаксис
Кір Новак

@KirNovak Дякую брате. Я також надав URL у мангусті для знецінення .
Tes3awy

25

Колекція collection.count застаріла і буде видалена в наступній версії. Використовуйте колекцію. кількістьДокументи або колекція замість цього оцінюєтьсяDocumentCount .

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

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

3
ось посилання на документацію: mongoosejs.com/docs/api.html#model_Model.estimatedDocumentCount
babar78

У мене виникла проблема, що в нашому проекті рутинна програма тестування існуючих предметів у будь-яких колекціях. Метод count () поводився дивно: коли колекція не була порожньою, вона іноді нічого не повертала (невизначена, нульова, нульова або помилкова - ми не могли її далі досліджувати). Ми все ще не з’ясували, що спричинило проблему, оскільки це був гоночний стан, який відбувся дуже рідко. Використання countDocuments ({}) зараз працює для нас. Дякую!
ha110_b1mm3lbahn

UnhandledPromiseRejectionWarning: TypeError: userModel.countDocuments is not a functionЯ отримую помилку під час використання її у власному користувальницькому моделі?
Люк Браун

Як ми можемо зробити "userModel.countDocuments" синхронним викликом, щоб я міг додати віртуальну схему, яка додає деякий "ключ і значення" в мій документ.
Сатьям

25

Ви повинні навести об’єкт як аргумент

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

або

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

або

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

У останній версії мангуста count () застарілий, тому використовуйте

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

2
DeprecationWarning: collection.count застарілий, замість цього слід використовувати .estimatedDocumentCount () або .countDocuments ().
HMagdy

9

Фон для рішення

Як зазначено в документації мангуста та у відповіді Бенджаміна, метод Model.count()застарілий. Замість використання count()альтернативами є наступні:

Model.countDocuments(filterObject, callback)

Підраховує кількість документів, які відповідають фільтру в колекції. Передача порожнього об'єкта {}, коли фільтр виконує сканування повної колекції. Якщо колекція велика, може бути використаний наступний метод.

Model.estimatedDocumentCount()

Цей модельний метод оцінює кількість документів у колекції MongoDB. Цей спосіб швидший, ніж попереднійcountDocuments() , оскільки він використовує метадані колекції замість того, щоб пройти всю колекцію. Однак, як підказує назва методу, і залежно від конфігурації db, результат є оцінкою, оскільки метадані можуть не відображати фактичну кількість документів у колекції в момент виконання методу.

Обидва методи повертають об'єкт запиту мангуста, який може бути виконаний одним із наступних двох способів. Використовуйте, .exec()якщо ви хочете виконати запит пізніше.

Рішення

Варіант 1: Передайте функцію зворотного дзвінка

Наприклад, порахуйте всі документи в колекції за допомогою .countDocuments():

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

Або порахуйте всі документи колекції, що мають певне ім’я, використовуючи .countDocuments():

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

Варіант 2: Використання .then()

У запиту мангуста є .then()Мангустний настільки "Thenable". Це для зручності, а сам запит не є обіцянкою.

Наприклад, порахуйте всі документи в колекції за допомогою .estimatedDocumentCount():

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

Варіант 3: Використовуйте функцію async / wait

Використовуючи підхід async / wait, рекомендованим способом є його використання, .exec()оскільки він забезпечує кращі сліди стека.

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

Навчання за допомогою stackoverflowing,


1

Тут найвищі відповіді, проголосовані ідеально, я просто хочу доповнити функцію очікування, щоб функцію, яку ви просили, можна архівувати:

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

Рекомендується використовувати countDocuments () над 'count ()', оскільки воно буде застарілим. Отже, на сьогодні ідеальним кодом було б:

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

-1

Як було сказано раніше, код не працюватиме так, як є. Рішенням цього може бути використання функції зворотного виклику, але якщо ви думаєте, що це призведе вас до пекла "Зворотний виклик", ви можете шукати "Promisses".

Можливе рішення за допомогою функції зворотного виклику:

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

якщо ви хочете шукати кількість документів на основі запиту, ви можете зробити це:

 userModel.count({yourQueryGoesHere}, setNumberofDocuments);

setNumberofDocuments - відокремлена функція:

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

        numberofDocs = count;

      };

Тепер ви можете отримати кількість документів у будь-якому місці за допомогою getFunction:

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

Крім того, ви використовуєте цю асинхронну функцію всередині синхронної, використовуючи зворотний виклик, наприклад:

function calculateNumberOfDoc(someParameter, setNumberofDocuments){

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

       setNumberofDocuments(true);


} 

Сподіваюся, що це може допомогти іншим. :)


У функції izračunaNumberOfDoc (), чому ви називаєте setNumberofDocuments (вірно)? Чи не призведе це спочатку до помилки, навіть до того, як буде повернуто фактичне підрахунок ??
pravin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.