db.collection bukan fungsi saat menggunakan MongoClient v3.0

132

Saya telah mencoba tutorial W3schools pada nodeJS dengan MongoDB.

Ketika saya mencoba menerapkan contoh ini di lingkungan nodeJS dan memanggil fungsi dengan panggilan AJAX, saya mendapatkan kesalahan di bawah ini:

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)

Silakan temukan di bawah ini kode yang saya implementasikan:

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

Perhatikan bahwa kesalahan terjadi setiap kali eksekusi mencapai:

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

Juga, perhatikan (jika penting) bahwa saya telah menginstal paket MongoDB terbaru untuk node JS ( npm install mongodb ), dan versi MongoDB adalah MongoDB Enterprise 3.4.4, dengan driver MongoDB Node.js v3.0.0-rc0.

Elie Asmar
sumber
Apakah Anda memastikan: (1) database berjalan (mengingat tidak ada kesalahan, saya kira begitu); (2) database mytestingdb ada (coba gunakan robomongo / robo3t untuk mengakses koneksi Anda dan melihat koleksi) (3) Pelanggan koleksi sebenarnya ada; Juga beri tahu kami bagaimana Anda memanggil skrip itu dan versi Nodejs apa (bagaimana Anda menginstal?)
nbkhope
Basis data dan koleksi ada (saya telah mengaksesnya menggunakan Studio 3t). Saya debugging nodeJS dengan memanggil metode melalui panggilan AJAX, pada dasarnya breakpoints sedang dipukul dan semuanya berfungsi dengan baik sampai saya mendapatkan pengecualian yang disebutkan di atas. Versi NodeJS adalah v6.11.4
Elie Asmar
Kemudian ganti kode yang dimulai dengan db.collection()...log konsol untuk melihat apakah ada di sana, tidak ada masalah.
nbkhope
Basis data dan koleksi ada (saya telah mengaksesnya menggunakan Studio 3t). Saya debugging nodeJS dengan memanggil metode melalui panggilan AJAX, pada dasarnya breakpoints sedang dipukul dan semuanya berfungsi dengan baik sampai saya mendapatkan pengecualian yang disebutkan di atas. Versi NodeJS adalah v6.11.4
Elie Asmar

Jawaban:

80

Saya mengalami hal yang sama. Di package.json, ubah baris mongodb ke "mongodb": "^ 2.2.33". Anda harus menghapus instalan mongodb; lalu npm install untuk menginstal versi ini.

Ini menyelesaikan masalah bagi saya. Tampaknya ada bug atau dokumen yang perlu diperbarui.

AyoO
sumber
15
memeriksa Mikas' jawaban
Hartmut
67
menurunkan versi ke versi yang lebih awal sebenarnya bukan solusi, itu hanya berarti Anda tidak repot-repot melihat perubahan API yang menyebabkan ini
John Culviner
3
@JohnCulviner - Ini adalah masalah waktu; bukan masalah kemalasan. Masalah ini terjadi ketika mereka sedang dalam proses merilis pembaruan baru. Saya (dan poster asli) jelas tidak menyadari hal ini. Pada saat itu, dokumen belum diperbarui. Mereka diperbarui tak lama setelah itu. Siapa pun yang ingin menyelesaikan ini sekarang harus mengikuti komentar MikaS dan meninjau dokumen yang diperbarui .. Saya melakukan hal yang sama setelah dokumen diperbarui dan dapat melanjutkan dengan versi yang ditingkatkan.
AyoO
1
Menghadapi ini sekarang - saya mengalami masalah ini dan memasang "mongodb:" "3.0.2" di package.json, apakah ada masalah dengan versi yang baru?
logos_164
4
Tidak membantu sama sekali. Mengapa ditandai sebagai jawaban yang benar?
CodingNow
482

Untuk orang-orang di versi 3.0 dari driver NodeJS asli MongoDB:

(Ini berlaku untuk orang dengan "mongodb": "^ 3.0.0-rc0", atau versi yang lebih baru di package.json, yang ingin tetap menggunakan versi terbaru.)

Dalam versi 2.x dari driver NodeJS asli MongoDB Anda akan mendapatkan objek database sebagai argumen ke callback koneksi:

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

Menurut changelog untuk 3.0 Anda sekarang mendapatkan objek klien yang berisi objek database sebagai gantinya:

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

The close()Metode juga telah dipindahkan ke klien. Kode dalam pertanyaan karena itu dapat diterjemahkan ke:

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();
  });
}); 
Mika Sundland
sumber
Sekarang apakah kita harus menulis var db = client.db('mytestingdb');baris ekstra ini ( ) setiap kali alih-alih menulis seperti ini saja ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? Saya selalu bekerja dengan database yang sama. Apakah ada pendekatan untuk menghilangkan garis tambahan itu? Ini seperti memakan waktu bagi saya.
ozgrozer
7
@ozgrozer Kedengarannya bagi saya seperti Anda terhubung ke db untuk setiap permintaan. Itu dianggap ide yang buruk. Anda dapat membacanya di sini . Jika Anda hanya terhubung satu kali, hanya ada satu baris baru per aplikasi yang Anda buat.
Mika Sundland
1
@MikaS Oh ya. Saya terhubung ke db seperti yang Anda katakan. Saya tidak tahu bahwa kita dapat terhubung sekali dan menggunakan kembali variabel db. Terima kasih banyak.
ozgrozer
1
Jawaban bagus; mencari tahu ini adalah waktu yang menyebalkan, saya harus ingat untuk RTFM
Mr.Budris
Saya memang mengimplementasikan klien seperti itu, tetapi masih ada masalah yang sama (db.collection bukan fungsi) di dalam \ node_modules \ mongodb \ lib \ gridfs-stream \ index.js: 50: 27
alex351
34

Bagi mereka yang ingin terus menggunakan versi ^ 3.0.1 waspadai perubahan cara Anda menggunakan MongoClient.connect()metode ini. Callback tidak kembali dbsebagai gantinya kembali client, di mana ada fungsi yang disebut db(dbname)bahwa Anda harus memanggil untuk mendapatkan dbcontoh yang Anda cari.

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();
});
ra9r
sumber
2
Jawaban ini lebih baru dan berlaku untuk versi 3 driver. Terima kasih
Mohammad
1
Saya merekomendasikan solusi ini, lebih cocok untuk referensi di masa mendatang.
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);
        });
    })
})

Satu-satunya masalah dengan kode Anda adalah bahwa Anda mengakses objek yang memegang pengendali database. Anda harus mengakses database secara langsung (lihat variabel database di atas). Kode ini akan mengembalikan database Anda dalam array dan kemudian loop melalui itu dan mencatat nama untuk semua orang di database.

Dre Jackson
sumber
Jawaban ini ditandai dengan kualitas rendah karena panjang dan isinya. Harap berikan informasi lebih lanjut.
Wahyu Kristianto
Itu hanya selama itu perlu. Jawaban ini membantu saya.
Manuel Hernandez
1
@ManuelHernandez senang itu membantu :)
Dre Jackson
ini adalah ans yang benar. Harap tandai ini sebagai ans yang benar.
Ninad Kambli
12

Piggy mendukung @MikkaS jawaban untuk Mongo Client v3.x, saya hanya memerlukan format async / wait, yang terlihat sedikit dimodifikasi seperti ini:

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.
}
agarcian
sumber
7

Saya melakukan sedikit percobaan untuk melihat apakah saya bisa menjaga nama database sebagai bagian dari url. Saya lebih suka sintaks janji tetapi masih harus bekerja untuk sintaks callback. Perhatikan di bawah ini bahwa client.db () dipanggil tanpa melewati parameter apa pun.

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 saya mencantumkan monbodb ^ 3.2.5.

Opsi 'useNewUrlParser' tidak diperlukan jika Anda bersedia untuk berurusan dengan peringatan penghentian. Tetapi sebaiknya gunakan pada saat ini sampai versi 4 keluar di mana driver yang baru mungkin akan menjadi default dan Anda tidak akan memerlukan opsi lagi.

pwilcox
sumber
5

Saya menyelesaikannya dengan mudah melalui menjalankan kode-kode ini:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Selamat Coding!

Saurabh Singh
sumber
4

Saya memiliki MongoDB shell versi v3.6.4, di bawah ini menggunakan kode mongoclient, Ini baik untuk saya:

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()");
 });
Gianluca Mazzeo
sumber
Pertanyaan ini berkaitan dengan driver node, bukan shell.
UpTheCreek
3

Jika seseorang masih mencoba cara mengatasi kesalahan ini, saya telah melakukan ini seperti di bawah ini.

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();
        });
    });
  });
});
Mahendra Bagul
sumber
Solusi ini dan @Dre Jackson adalah yang bekerja dengan simpul pada 07/2020. Sepertinya apa yang diteruskan sebagai argumen ke callback terhubung adalah MongoClient daripada db, itulah sebabnya Anda perlu mengambil db darinya. Selain itu, solusi ini juga mencantumkan useUnifiedTopology: true, yang juga dibutuhkan saat ini.
Coffee_fan
1

Kueri MongoDB mengembalikan kursor ke array yang tersimpan di memori. Untuk mengakses hasil array itu, Anda harus menelepon .toArray()di akhir permintaan.

  db.collection("customers").find({}).toArray() 
pmpc2
sumber