db.collection ไม่ใช่ฟังก์ชันเมื่อใช้ MongoClient v3.0


132

ฉันได้ลองใช้การสอน W3schools บน nodeJS กับ MongoDB แล้ว

เมื่อฉันพยายามใช้ตัวอย่างนี้ในสภาพแวดล้อม nodeJS และเรียกใช้ฟังก์ชันด้วยการเรียก AJAX ฉันได้รับข้อผิดพลาดด้านล่าง:

TypeError: db.collection is not a function
    at c:\Users\user\Desktop\Web Project\WebService.JS:79:14
    at args.push (c:\Users\user\node_modules\mongodb\lib\utils.js:431:72)
    at c:\Users\user\node_modules\mongodb\lib\mongo_client.js:254:5
    at connectCallback (c:\Users\user\node_modules\mongodb\lib\mongo_client.js:933:5)
    at c:\Users\user\node_modules\mongodb\lib\mongo_client.js:794:11
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)

โปรดค้นหารหัสที่ฉันนำไปใช้ด้านล่าง:

var MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/mytestingdb";

MongoClient.connect(url, function(err, db) {
  if (err) throw err;
  db.collection("customers").findOne({}, function(err, result) {
    if (err) throw err;
    console.log(result.name);
    db.close();
  });
});

โปรดทราบว่าข้อผิดพลาดเกิดขึ้นทุกครั้งที่การดำเนินการเข้าชม:

db.collection("customers").findOne({}, function(err, result) {}

นอกจากนี้ให้สังเกต (ในกรณีที่เป็นเรื่องสำคัญ) ที่ฉันได้ติดตั้งแพ็คเกจ MongoDB ล่าสุดสำหรับโหนด JS ( npm ติดตั้ง mongodb ) และรุ่น MongoDB คือ MongoDB Enterprise 3.4.4 พร้อมไดรเวอร์ MongoDB Node.js v3.0.0-rc0


คุณแน่ใจหรือไม่: (1) ฐานข้อมูลกำลังทำงานอยู่ (เนื่องจากไม่มีข้อผิดพลาดฉันเดาอย่างนั้น); (2) ฐานข้อมูล mytestingdb มีอยู่ (ลองใช้ robomongo / robo3t เพื่อเข้าถึงการเชื่อมต่อของคุณและดูคอลเลกชัน) (3) มีการรวบรวมลูกค้าจริง ๆ ; บอกเราด้วยว่าคุณกำลังเรียกใช้สคริปต์นั้นและรุ่นใดของ Nodejs (คุณติดตั้งอย่างไร?)
nbkhope

ฐานข้อมูลและคอลเลกชันมีอยู่ (ฉันเข้าถึงได้โดยใช้ Studio 3t) ฉันกำลังดีบัก nodeJS โดยเรียกใช้เมธอดผ่านการเรียก AJAX โดยทั่วไปแล้วจุดพักถูกโจมตีและทุกอย่างทำงานได้ดีจนกระทั่งฉันได้รับข้อยกเว้นตามที่ระบุไว้ข้างต้น รุ่น NodeJS คือ v6.11.4
Elie Asmar

จากนั้นแทนที่รหัสที่ขึ้นต้นด้วยdb.collection()...บันทึกของคอนโซลเพื่อดูว่ามันไปถึงที่นั่นหรือไม่ไม่มีปัญหา
nbkhope

ฐานข้อมูลและคอลเลกชันมีอยู่ (ฉันเข้าถึงได้โดยใช้ Studio 3t) ฉันกำลังดีบัก nodeJS โดยเรียกใช้เมธอดผ่านการเรียก AJAX โดยทั่วไปแล้วจุดพักถูกโจมตีและทุกอย่างทำงานได้ดีจนกระทั่งฉันได้รับข้อยกเว้นตามที่ระบุไว้ข้างต้น รุ่น NodeJS คือ v6.11.4
Elie Asmar

คำตอบ:


80

ฉันพบสิ่งเดียวกัน ใน package.json เปลี่ยนบรรทัด mongodb เป็น "mongodb": "^ 2.2.33" คุณจะต้องถอนการติดตั้งเอ็นเอ็มพี MongoB; จากนั้นติดตั้ง npm เพื่อติดตั้งเวอร์ชันนี้

การแก้ไขปัญหาสำหรับฉัน ดูเหมือนว่าจะเป็นข้อผิดพลาดหรือเอกสารจะต้องมีการปรับปรุง


15
ตรวจสอบคำตอบของ MikaS
hartmut

67
การลดระดับเป็นรุ่นก่อนหน้านี้ไม่ได้เป็นวิธีแก้ปัญหา แต่ก็หมายความว่าคุณไม่ต้องกังวลกับการเปลี่ยนแปลงของ API ที่ทำให้เกิดปัญหานี้
John Culviner

3
@JohnCulviner - นี่เป็นปัญหาเวลา ไม่ใช่เรื่องขี้เกียจ ปัญหานี้เกิดขึ้นขณะที่พวกเขาอยู่ในกระบวนการของการปล่อยการปรับปรุงใหม่ ฉัน (และโปสเตอร์ดั้งเดิม) เห็นได้ชัดว่าไม่ได้ตระหนักถึงเรื่องนี้ ในขณะนั้นเอกสารยังไม่ได้อัปเดต พวกเขาได้รับการปรับปรุงหลังจากนั้นไม่นาน ทุกคนที่ต้องการแก้ไขปัญหานี้ ณ ตอนนี้ควรทำตามความคิดเห็นของ MikaS และตรวจสอบเอกสารที่อัปเดตแล้ว .. ฉันทำเช่นเดียวกันหลังจากเอกสารได้รับการอัปเดตแล้วและสามารถดำเนินการต่อกับรุ่นที่อัปเกรดได้
AyoO

1
เจอสิ่งนี้ตอนนี้ - ฉันพบปัญหานี้และติดตั้ง "mongodb:" "3.0.2" ใน package.json มีปัญหากับเวอร์ชันใหม่หรือไม่
logos_164

4
ไม่ช่วยเลย เหตุใดจึงถูกตั้งค่าสถานะเป็นคำตอบที่ถูกต้อง
CodingNow

482

สำหรับคนที่ใช้งานเวอร์ชั่น 3.0 ของ MongoDB native NodeJS driver:

(สิ่งนี้ใช้ได้กับผู้ที่มี "mongodb": "^ 3.0.0-rc0" หรือรุ่นที่ใหม่กว่าใน package.json ที่ต้องการใช้รุ่นล่าสุดต่อไป)

ในเวอร์ชั่น 2.x ของไดรเวอร์ MongoDB เนทิฟ NodeJSคุณจะได้รับวัตถุฐานข้อมูลเป็นอาร์กิวเมนต์ในการติดต่อกลับโทร:

MongoClient.connect('mongodb://localhost:27017/mytestingdb', (err, db) => {
  // Database returned
});

ตามการเปลี่ยนแปลงของ 3.0 คุณจะได้รับวัตถุไคลเอนต์ที่มีวัตถุฐานข้อมูลแทน:

MongoClient.connect('mongodb://localhost:27017', (err, client) => {
  // Client returned
  var db = client.db('mytestingdb');
});

close()วิธีการยังได้รับการย้ายไปยังลูกค้า รหัสในคำถามจึงสามารถแปลเป็น:

MongoClient.connect('mongodb://localhost', function (err, client) {
  if (err) throw err;

  var db = client.db('mytestingdb');

  db.collection('customers').findOne({}, function (findErr, result) {
    if (findErr) throw findErr;
    console.log(result.name);
    client.close();
  });
}); 

ตอนนี้เราต้องเขียนvar db = client.db('mytestingdb');บรรทัดพิเศษ( ) นี้ทุกครั้งแทนที่จะเขียนแค่นี้ ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? ฉันทำงานกับฐานข้อมูลเดียวกันอยู่เสมอ มีวิธีใดที่จะกำจัดเส้นพิเศษนั้นหรือไม่? มันเหมือนกับสิ่งที่ใช้เวลานานสำหรับฉัน
ozgrozer

7
@ozgrozer ฟังดูราวกับว่าคุณกำลังเชื่อมต่อกับ db สำหรับทุกคำขอ นั่นถือว่าเป็นความคิดที่ไม่ดี คุณสามารถอ่านเกี่ยวกับเรื่องนี้ที่นี่ หากคุณเชื่อมต่อเพียงครั้งเดียวจะมีหนึ่งบรรทัดใหม่ต่อแอพที่คุณสร้าง
Mika Sundland

1
@MikaS โอ้ใช่ ฉันกำลังเชื่อมต่อกับฐานข้อมูลอย่างที่คุณพูด ฉันไม่รู้ว่าเราสามารถเชื่อมต่อได้ครั้งเดียวและใช้ตัวแปร db ซ้ำอีกครั้ง ขอบคุณมาก.
ozgrozer

1
คำตอบที่ดี; การคิดออกนี้เป็นเวลาดูดฉันควรจำ RTFM
Mr.Budris

ฉันใช้ไคลเอนต์เช่นนั้น แต่ยังคงมีปัญหาเดียวกัน (db.collection ไม่ใช่ฟังก์ชัน) ภายใน \ node_modules \ mongodb \ lib \ gridfs-stream \ index.js: 50: 27
alex351

34

สำหรับผู้ที่ต้องการใช้เวอร์ชัน ^ 3.0.1 ต่อไปโปรดระวังการเปลี่ยนแปลงวิธีการใช้งานของMongoClient.connect()คุณ การเรียกกลับไม่กลับมาdbแทนclientซึ่งจะมีฟังก์ชันที่เรียกdb(dbname)ว่าคุณต้องเรียกใช้เพื่อรับdbอินสแตนซ์ที่คุณต้องการ

const MongoClient = require('mongodb').MongoClient;
const assert = require('assert');

// Connection URL
const url = 'mongodb://localhost:27017';

// Database Name
const dbName = 'myproject';

// Use connect method to connect to the server
MongoClient.connect(url, function(err, client) {
  assert.equal(null, err);
  console.log("Connected successfully to server");

  const db = client.db(dbName);

  client.close();
});

2
คำตอบนี้เป็นคำตอบล่าสุดและใช้กับไดร์เวอร์เวอร์ชัน 3 ขอบคุณ
Mohammad

1
ฉันแนะนำโซลูชันนี้มันเหมาะสำหรับการอ้างอิงในอนาคต
Jamie Nicholl-Shelley

31
MongoClient.connect(url (err, client) => {
    if(err) throw err;

    let database = client.db('databaseName');

    database.collection('name').find()
    .toArray((err, results) => {
        if(err) throw err;

        results.forEach((value)=>{
            console.log(value.name);
        });
    })
})

ปัญหาเดียวกับรหัสของคุณคือคุณกำลังเข้าถึงวัตถุที่ถือตัวจัดการฐานข้อมูล คุณต้องเข้าถึงฐานข้อมูลโดยตรง (ดูตัวแปรฐานข้อมูลด้านบน) รหัสนี้จะส่งคืนฐานข้อมูลของคุณในอาร์เรย์จากนั้นจะวนซ้ำและบันทึกชื่อของทุกคนในฐานข้อมูล


คำตอบนี้ถูกทำเครื่องหมายว่ามีคุณภาพต่ำเนื่องจากความยาวและเนื้อหา กรุณาให้ข้อมูลเพิ่มเติม
Wahyu Kristianto

เป็นเพียงตราบเท่าที่มันจำเป็นต้องมี คำตอบนี้ช่วยฉัน
Manuel Hernandez

1
@ ManuelHernandez ดีใจที่มันช่วย :)
Dre Jackson

นี่คือคำตอบที่ถูกต้อง โปรดทำเครื่องหมายว่านี่เป็นคำตอบที่ถูกต้อง
Ninad Kambli

12

การสำรอง Piggy บน @MikkaS คำตอบสำหรับ Mongo Client v3.x ฉันต้องการรูปแบบ async / await ซึ่งมีการปรับเปลี่ยนเล็กน้อยดังนี้:

const myFunc = async () => {

     // Prepping here...


    // Connect
    let client = await MongoClient.connect('mongodb://localhost');
    let db = await client.db();

    // Run the query
    let cursor = await db.collection('customers').find({});

    // Do whatever you want on the result.
}

7

ฉันทำการทดลองเล็กน้อยเพื่อดูว่าฉันสามารถใช้ชื่อฐานข้อมูลเป็นส่วนหนึ่งของ URL ได้หรือไม่ ฉันชอบไวยากรณ์ของสัญญา แต่ก็ยังควรใช้งานได้สำหรับไวยากรณ์การโทรกลับ โปรดสังเกตด้านล่างว่า client.db () ถูกเรียกโดยไม่ผ่านพารามิเตอร์ใด ๆ

MongoClient.connect(
    'mongodb://localhost:27017/mytestingdb', 
    { useNewUrlParser: true}
)
.then(client => {

    // The database name is part of the url.  client.db() seems 
    // to know that and works even without a parameter that 
    // relays the db name.
    let db = client.db(); 

    console.log('the current database is: ' + db.s.databaseName);
    // client.close() if you want to

})
.catch(err => console.log(err));

package.json ของฉันแสดง monbodb ^ 3.2.5

ตัวเลือก 'useNewUrlParser' ไม่จำเป็นถ้าคุณยินดีที่จะจัดการกับคำเตือนการคัดค้าน แต่ก็ควรใช้ ณ จุดนี้จนกว่าเวอร์ชั่น 4 จะออกมาซึ่งน่าจะเป็นไดรเวอร์ใหม่ที่เป็นค่าเริ่มต้นและคุณไม่จำเป็นต้องใช้ตัวเลือกอีกต่อไป


5

ฉันแก้ไขได้อย่างง่ายดายผ่านการเรียกใช้รหัสเหล่านี้:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Happy Coding!


4

ฉันมี MongoDB เชลล์เวอร์ชัน v3.6.4, โค้ดด้านล่างใช้ MongoClient, มันดีสำหรับฉัน:

var MongoClient = require('mongodb').MongoClient,
assert = require('assert');
var url = 'mongodb://localhost:27017/video';
MongoClient.connect(url,{ useNewUrlParser: true }, function(err, client) 
{
assert.equal(null, err);
console.log("Successfully connected to server");
var db = client.db('video');
// Find some documents in our collection
db.collection('movies').find({}).toArray(function(err, docs) {
// Print the documents returned
docs.forEach(function(doc) {
console.log(doc.title);
});
// Close the DB
client.close();
});
// Declare success
console.log("Called find()");
 });

คำถามนี้เกี่ยวข้องกับไดรเวอร์โหนดไม่ใช่เชลล์
UpTheCreek

3

หากมีคนยังคงพยายามที่จะแก้ไขข้อผิดพลาดนี้ฉันได้ทำเช่นนี้ด้านล่าง

const MongoClient = require('mongodb').MongoClient;
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'mytestingdb';

const retrieveCustomers = (db, callback)=>{
    // Get the customers collection
    const collection = db.collection('customers');
    // Find some customers
    collection.find({}).toArray((err, customers) =>{
        if(err) throw err;
      console.log("Found the following records");
      console.log(customers)
      callback(customers);
    });
}

const retrieveCustomer = (db, callback)=>{
    // Get the customers collection
    const collection = db.collection('customers');
    // Find some customers
    collection.find({'name': 'mahendra'}).toArray((err, customers) =>{
        if(err) throw err;
      console.log("Found the following records");
      console.log(customers)
      callback(customers);
    });
}

const insertCustomers = (db, callback)=> {
    // Get the customers collection
    const collection = db.collection('customers');
    const dataArray = [{name : 'mahendra'}, {name :'divit'}, {name : 'aryan'} ];
    // Insert some customers
    collection.insertMany(dataArray, (err, result)=> {
        if(err) throw err;
        console.log("Inserted 3 customers into the collection");
        callback(result);
    });
}

// Use connect method to connect to the server
MongoClient.connect(url,{ useUnifiedTopology: true }, (err, client) => {
  console.log("Connected successfully to server");
  const db = client.db(dbName);
  insertCustomers(db, ()=> {
    retrieveCustomers(db, ()=> {
        retrieveCustomer(db, ()=> {
            client.close();
        });
    });
  });
});

โซลูชันนี้และ @Dre Jackson เป็นโซลูชันที่ทำงานกับโหนดตั้งแต่ 07/2020 ดูเหมือนว่าสิ่งที่ส่งผ่านเป็นอาร์กิวเมนต์ไปยังการติดต่อกลับเป็น MongoClient มากกว่า db ซึ่งเป็นเหตุผลที่คุณต้องดึง db จากมัน นอกเหนือจากนั้นโซลูชันนี้ยังแสดงรายการuseUnifiedTopology: trueซึ่งจำเป็นต้องใช้ในปัจจุบันด้วย
Coffee_fan

1

คำสั่ง MongoDB ส่งคืนเคอร์เซอร์ไปยังอาร์เรย์ที่เก็บไว้ในหน่วยความจำ ในการเข้าถึงผลลัพธ์ของอาเรย์นั้นคุณต้องโทรหา.toArray()เมื่อสิ้นสุดการสืบค้น

  db.collection("customers").find({}).toArray() 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.