วิธีการนับแบบจำลองพังพอนทั้งหมด?


104

ฉันจะทราบจำนวนโมเดลที่บันทึกข้อมูลได้อย่างไร มีวิธีการหนึ่ง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เป็น Object วิธีcountไหนที่เรียกว่าได้ของจริง

ขอบคุณ


1
หากคุณใช้ ES 2016 คุณสามารถตัดการโทรเพื่อนับภายในสัญญาและเรียกใช้ด้วยเครื่องกำเนิดไฟฟ้า
mikeyGlitz

คำตอบ:


127

โค้ดด้านล่างใช้งานได้ หมายเหตุการใช้งานของ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);
      });
   }
 }); 

151

สาเหตุที่รหัสของคุณไม่ทำงานเนื่องจากฟังก์ชันการนับเป็นแบบอะซิงโครนัสจึงไม่ส่งคืนค่าพร้อมกัน

นี่คือตัวอย่างการใช้งาน:

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

ยกตัวอย่างวิธีการนับวิธีซิงโครนัส
sankar muniyappa

เหมือนกับฉัน. ฉันกำลังมองหาสิ่งเดียวกัน
nowox

13
countเมธอดถูกยกเลิกคุณสามารถใช้countDocumentsไวยากรณ์เดียวกันได้
Kir Novak

@KirNovak ขอบคุณครับ ผมยังให้ URL ในพังพอนสำหรับการเลิกใช้
Tes3awy

27

คุณควรให้วัตถุเป็นอาร์กิวเมนต์

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 เลิกใช้แล้วคุณควรใช้ .estimateDocumentCount () หรือ .countDocuments () แทน
HMagdy

26

collection.count เลิกใช้งานแล้วและจะถูกลบออกในอนาคต ใช้คอลเลกชัน countDocumentsหรือคอลเลกชัน ApproxDocumentCountแทน

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

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

3
นี่คือลิงค์เอกสาร: mongoosejs.com/docs/api.html#model_Model.estimateDocumentCount
babar78

ฉันมีปัญหาว่าในโครงการของเรามีการทดสอบขั้นตอนการตั้งค่าสำหรับรายการที่มีอยู่ในคอลเล็กชัน เมธอด count () ทำงานแปลก ๆ : เมื่อคอลเลกชันไม่ว่างเปล่าบางครั้งก็ไม่ส่งคืนอะไรเลย (ไม่ได้กำหนดค่าว่างศูนย์หรือเท็จเราไม่สามารถตรวจสอบเพิ่มเติมได้) เรายังไม่พบว่าอะไรเป็นสาเหตุของปัญหาเนื่องจากเป็นสภาวะการแข่งขันที่ไม่ค่อยเกิดขึ้น การใช้ countDocuments ({}) ใช้ได้ผลกับเราแล้ว ขอบคุณ!
ha110_b1mm3lbahn

UnhandledPromiseRejectionWarning: TypeError: userModel.countDocuments is not a functionฉันได้รับข้อผิดพลาดเมื่อใช้กับ userModel ของฉันเอง?
ลุคบราวน์

เราจะทำให้ "userModel.countDocuments" เป็นการเรียกแบบซิงโครนัสได้อย่างไรเพื่อที่ฉันจะสามารถเพิ่มเสมือนให้กับสคีมาที่เพิ่ม "คีย์และค่า" ในเอกสารของฉันได้
Satyam

10

ความเป็นมาของการแก้ปัญหา

ตามที่ระบุไว้ในเอกสารพังพอนและในคำตอบของเบนจามินวิธี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()ดังนั้นจึง "ใช้แล้วได้" เพื่อความสะดวกและการสืบค้นนั้นไม่ใช่คำมั่นสัญญา

ตัวอย่างเช่นนับเอกสารทั้งหมดในคอลเล็กชันโดยใช้.estimatedDocumentCount():

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

ตัวเลือกที่ 3: ใช้ async / await

เมื่อใช้วิธี async / await วิธีที่แนะนำคือใช้ร่วมกับ.exec()สแต็กเทรซที่ดีกว่า

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

การเรียนรู้โดยการซ้อนทับ


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

0

การใช้ mongoose.js คุณสามารถนับเอกสารได้

const count = await Schema.countDocuments(); // count all

const count = await Schema.countDocuments({ key: value }); // count specific


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


} 

หวังว่ามันจะช่วยคนอื่นได้ :)


ในฟังก์ชันคำนวณNumberOfDoc () เหตุใดคุณจึงเรียกใช้ setNumberofDocuments (true) จะไม่ส่งผลให้เกิดข้อผิดพลาดก่อนแม้ว่าจะส่งคืนการนับจริงหรือไม่ ??
pravin
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.