MongoClient v3.0 kullanılırken db.collection bir işlev değildir


132

Ben çalışıyorlar W3Schools öğretici MongoDB ile nodeJS üzerinde.

Bu örneği bir nodeJS ortamında uygulamaya çalıştığımda ve işlevi bir AJAX çağrısıyla çağırdığımda, aşağıdaki hatayı aldım:

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)

Lütfen aşağıda uygulanan kodumu bulun:

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

Çalıştırma gerçekleştiğinde hatanın oluştuğunu unutmayın:

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

Ayrıca, (önemli olması durumunda) node JS için en son MongoDB paketini ( npm install mongodb ) kurduğumu ve MongoDB sürümünün MongoDB Node.js sürücüsü v3.0.0-rc0 ile MongoDB Enterprise 3.4.4 olduğunu unutmayın.


Şunlardan emin misiniz: (1) veritabanı çalışıyor (hata olmadığı için, sanırım öyle); (2) mytestingdb veritabanı var (bağlantınıza erişmek ve koleksiyonları görmek için robomongo / robo3t kullanmayı deneyin) (3) Koleksiyon müşterileri gerçekten var; Ayrıca bize bu betiği nasıl çağırdığınızı ve Nodejs'nin hangi sürümünü (nasıl yüklediniz?)
nbkhope

Veritabanı ve koleksiyon mevcut (bunlara Studio 3t kullanarak eriştim). Bir AJAX çağrısı aracılığıyla yöntemi çağırarak nodeJS'de hata ayıklıyorum, temelde kesme noktaları vuruluyor ve yukarıda belirtilen istisnayı alana kadar her şey yolunda gidiyor. NodeJS sürümü v6.11.4
Elie Asmar

Ardından db.collection()..., oraya ulaşıp ulaşmadığını görmek için bir konsol günlüğü ile başlayan kodu değiştirin, sorun yok.
nbkhope

Veritabanı ve koleksiyon mevcut (bunlara Studio 3t kullanarak eriştim). Bir AJAX çağrısı aracılığıyla yöntemi çağırarak nodeJS'de hata ayıklıyorum, temelde kesme noktaları vuruluyor ve yukarıda belirtilen istisnayı alana kadar her şey yolunda gidiyor. NodeJS sürümü v6.11.4
Elie Asmar

Yanıtlar:


79

Ben de aynı şeyle karşılaştım. Package.json içinde, mongodb satırını "mongodb": "^ 2.2.33" olarak değiştirin. Mongodb'yi npm kaldırmanız gerekecek; sonra bu sürümü kurmak için npm install.

Bu benim için sorunu çözdü. Bir hata gibi görünüyor veya dokümanların güncellenmesi gerekiyor.


15
Mikas' cevabı kontrol et
Hartmut

67
Daha önceki bir sürüme düşürmek gerçekten bir çözüm değildir, bu sadece buna neden olan API değişikliklerine bakmakla uğraşmadığınız anlamına gelir
John Culviner

3
@JohnCulviner - Bu bir zamanlama sorunuydu; tembellik sorunu değil. Bu sorun, yeni güncellemeyi yayınlama sürecindeyken meydana geldi. Ben (ve orijinal afiş) açıkça bunun farkında değildim. O sırada dokümanlar henüz güncellenmemişti. Kısa bir süre sonra güncellendi. Şu an itibariyle bu sorunu çözmek isteyenler MikaS'ın yorumunu takip etmeli ve güncellenmiş dokümanları incelemelidir .. Aynı şeyi dokümanlar güncellendikten sonra yaptım ve yükseltilmiş sürüme devam edebildim.
AyoO

1
Şimdi bununla karşılaşıyorum - bu sorunla karşılaşıyordum ve package.json'da "mongodb:" "3.0.2" yüklüydü, yeni sürümde sorunlar var mı?
logos_164

4
Hiç yardımcı olmuyor. Neden doğru cevap olarak işaretleniyor?
CodingNow

482

MongoDB yerel NodeJS sürücüsünün 3.0 sürümünü kullanan kişiler için:

(Bu, en son sürümü kullanmaya devam etmek isteyen "mongodb": "^ 3.0.0-rc0" veya package.json içinde daha sonraki bir sürüme sahip kişiler için geçerlidir.)

MongoDB yerel NodeJS sürücüsünün 2.x sürümünde , veritabanı nesnesini connect geri aramasına bir argüman olarak alırsınız:

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

3.0 için değişiklik günlüğüne göre artık bunun yerine veritabanı nesnesini içeren bir istemci nesnesi elde edersiniz:

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

close()Yöntem ayrıca, müşteriye taşındı. Bu nedenle, sorudaki kod şu dile çevrilebilir:

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

Şimdi var db = client.db('mytestingdb');her seferinde bu ( MongoClient.connect('mongodb://localhost:27017/mytestingdb')) gibi yazmak yerine bu ( ) ekstra satırı yazmamız gerekiyor mu? Hep aynı veri tabanıyla çalışıyorum. Bu fazladan çizgiyi ortadan kaldıracak herhangi bir yaklaşım var mı? Bu benim için zaman alıcı bir şey gibi.
ozgrozer

7
@ozgrozer Her istek için db'ye bağlanıyormuşsunuz gibi geliyor bana. Bu kötü bir fikir olarak kabul edildi. Buradan okuyabilirsiniz . Yalnızca bir kez bağlanırsanız, oluşturduğunuz uygulama başına yalnızca bir yeni satır vardır.
Mika Sundland

1
@MikaS Oh evet. Dediğin gibi veritabanına bağlanıyordum. Bir kez bağlanıp db değişkenini yeniden kullanabileceğimizi bilmiyordum. Çok teşekkür ederim.
ozgrozer

1
Mükemmel cevap; bunun tam bir zaman olduğunu
anlamak, RTFM'yi

İstemciyi böyle uyguladım, ancak yine de \ node_modules \ mongodb \ lib \ gridfs-stream \ index.js: 50: 27
alex351

34

^ 3.0.1 sürümünü kullanmaya devam etmek isteyenler, MongoClient.connect()yöntemi kullanma şeklinizle ilgili değişikliklerin farkında olun . Geri çağırma geri dbdönmez client, bunun yerine , aradığınız örneği db(dbname)elde etmek için çağırmanız gereken bir işlevin bulunduğu bir işlev vardır 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
Bu cevap daha yenidir ve sürücünün 3. sürümü için geçerlidir. Teşekkürler
Mohammad

1
Bu çözümü tavsiye ederim, ileride başvurmak için daha uygundur.
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);
        });
    })
})

Kodunuzla ilgili tek sorun, veritabanı işleyicisini tutan nesneye erişiyor olmanızdır. Veritabanına doğrudan erişmelisiniz (yukarıdaki veritabanı değişkenine bakın). Bu kod, veritabanınızı bir dizi içinde döndürür ve ardından onun içinden geçer ve veritabanındaki herkesin adını günlüğe kaydeder.


Bu cevap, uzunluğu ve içeriği nedeniyle düşük kaliteli olarak işaretlenmiştir. Lütfen daha fazla bilgi verin.
Calderon Kristianto

Sadece olması gerektiği sürece. Bu cevap bana yardımcı oldu.
Manuel Hernandez

1
@ManuelHernandez yardımcı olduğuna sevindim :)
Dre Jackson

bu doğru ans. Lütfen bunu doğru bir yanıt olarak işaretleyin.
Ninad Kambli

12

Mongo Client v3.x için @MikkaS cevabında Piggy desteği, sadece aşağıdaki gibi biraz değiştirilmiş görünen async / await formatına ihtiyacım vardı:

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

Veritabanı adını url'nin bir parçası olarak tutup tutamayacağımı görmek için biraz deney yaptım. Promise sözdizimini tercih ederim ama yine de geri arama sözdizimi için çalışmalıdır. Aşağıda, client.db () 'nin herhangi bir parametre aktarılmadan çağrıldığına dikkat edin.

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'i listeliyor.

Bir kullanımdan kaldırma uyarısıyla uğraşmak istiyorsanız 'useNewUrlParser' seçeneği gerekli değildir. Ancak bu noktada, muhtemelen yeni sürücünün varsayılan olduğu ve artık seçeneğe ihtiyacınız olmayacağı 4. sürüm çıkana kadar kullanmak akıllıca olacaktır.


5

Bu kodları çalıştırarak kolayca çözdüm:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Mutlu Kodlama!


4

MongoDB kabuk sürüm v3.6.4'e sahibim, kodun altında mongoclient kullan, Benim için iyi:

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

Bu soru, kabukla değil, düğüm sürücüsüyle ilgilidir.
UpTheCreek

3

Birisi hala bu hatayı nasıl çözeceğini deniyorsa, bunu aşağıdaki gibi yaptım.

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

Bu çözüm ve @Dre Jackson biri, 07/2020 itibariyle node ile çalışan çözümlerdir. Görünüşe göre connect geri aramasına argüman olarak iletilen şey bir db'den çok MongoClient'tir, bu yüzden db'yi ondan almanız gerekir. Bunun dışında bu çözüm useUnifiedTopology: true, günümüzde ihtiyaç duyulanları da listeler .
Coffee_fan

1

MongoDB sorguları, bellekte depolanan bir diziye bir imleci döndürür. Bu dizinin sonucuna erişmek .toArray()için sorgunun sonunda aramanız gerekir .

  db.collection("customers").find({}).toArray() 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.