db.collection non è una funzione quando si utilizza MongoClient v3.0


132

Ho provato il tutorial di W3schools su nodeJS con MongoDB.

Quando provo a implementare questo esempio in un ambiente nodeJS e invoco la funzione con una chiamata AJAX, ho ricevuto l'errore di seguito:

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)

Di seguito trovi il mio codice implementato:

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

Si noti che l'errore si verifica ogni volta che si verifica l'esecuzione:

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

Inoltre, notare (nel caso in cui sia importante) che ho installato il pacchetto MongoDB più recente per il nodo JS ( npm install mongodb ) e che la versione MongoDB è MongoDB Enterprise 3.4.4, con il driver MongoDB Node.js v3.0.0-rc0.


Ti sei assicurato: (1) il database è in esecuzione (dato che non ci sono stati errori, credo); (2) esiste il database mytestingdb (prova ad usare robomongo / robo3t per accedere alla tua connessione e vedere le raccolte) (3) I clienti della raccolta effettivamente esistono; Dicci anche come stai chiamando quello script e quale versione di Nodejs (come hai installato?)
nbkhope,

Il database e la collezione esistono (li ho acceduti usando Studio 3t). Sto eseguendo il debug di nodeJS chiamando il metodo tramite una chiamata AJAX, sostanzialmente i punti di interruzione vengono colpiti e tutto funziona bene fino a quando non ottengo l'eccezione sopra indicata. La versione di NodeJS è v6.11.4
Elie Asmar il

Quindi sostituire il codice che inizia con db.collection()...un registro della console per vedere se arriva lì, nessun problema.
nbkhope,

Il database e la collezione esistono (li ho acceduti usando Studio 3t). Sto eseguendo il debug di nodeJS chiamando il metodo tramite una chiamata AJAX, sostanzialmente i punti di interruzione vengono colpiti e tutto funziona bene fino a quando non ottengo l'eccezione sopra indicata. La versione di NodeJS è v6.11.4
Elie Asmar il

Risposte:


80

Ho incontrato la stessa cosa. In package.json, cambia la riga mongodb in "mongodb": "^ 2.2.33". Sarà necessario disinstallare npm mongodb; quindi npm install per installare questa versione.

Questo ha risolto il problema per me. Sembra essere un bug o i documenti devono essere aggiornati.


15
controlla la risposta di MikaS
hartmut,

67
il downgrade a una versione precedente non è in realtà una soluzione, significa solo che non ti sei preoccupato di esaminare le modifiche all'API che hanno causato questo
John Culviner,

3
@JohnCulviner - Questo era un problema di temporizzazione; non è un problema di pigrizia. Questo problema si è verificato durante il rilascio del nuovo aggiornamento. Io (e il poster originale) ovviamente non me ne sono reso conto. A quel tempo, i documenti non erano ancora stati aggiornati. Sono stati aggiornati poco dopo. Chiunque cerchi di risolvere questo problema fin d'ora dovrebbe seguire il commento di MikaS e rivedere i documenti aggiornati. Ho fatto lo stesso dopo che i documenti sono stati aggiornati e sono stato in grado di continuare con la versione aggiornata.
AyoO

1
Mi sono imbattuto ora in questo problema: stavo incontrando questo problema e avevo "mongodb:" "3.0.2" installato in package.json, ci sono problemi con la nuova versione?
logos_164,

4
Non aiuta affatto. Perché è contrassegnato come la risposta corretta?
CodingOow

482

Per le persone con la versione 3.0 del driver NodeJS nativo MongoDB:

(Questo è applicabile alle persone con "mongodb": "^ 3.0.0-rc0", o una versione successiva in package.json, che vogliono continuare a utilizzare l'ultima versione.)

Nella versione 2.x del driver NodeJS nativo MongoDB si otterrebbe l'oggetto database come argomento per il callback di connessione:

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

Secondo il log delle modifiche per 3.0 ora si ottiene invece un oggetto client contenente l'oggetto database:

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

Il close()metodo è stato anche spostato sul client. Il codice nella domanda può quindi essere tradotto in:

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

Ora dobbiamo scrivere var db = client.db('mytestingdb');ogni volta questa ( ) riga in più invece di scrivere così ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? Lavoro sempre con lo stesso database. Esiste un approccio per eliminare quella linea in più? È un po 'come una cosa che richiede tempo per me.
ozgrozer,

7
@ozgrozer Mi sembra che ti stia collegando al db per ogni richiesta. È considerata una cattiva idea. Puoi leggerlo qui . Se ti connetti solo una volta c'è solo una nuova linea per app che crei.
Mika Sundland,

1
@MikaS Oh si. Mi stavo collegando al db come hai detto. Non sapevo che potessimo collegarci una volta e riutilizzare la variabile db. Grazie mille.
ozgrozer,

1
Bella risposta; capire che questo è stato un tempo schifoso, dovrei ricordare a RTFM
Mr.Brisris il

Ho implementato il client in questo modo, ma ci sono ancora gli stessi problemi (db.collection non è una funzione) all'interno di \ node_modules \ mongodb \ lib \ gridfs-stream \ index.js: 50: 27
alex351

34

Per coloro che desiderano continuare a utilizzare la versione ^ 3.0.1, tenere presente le modifiche apportate al modo in cui si utilizza il MongoClient.connect()metodo. Il callback non restituisce dbinvece restituisce client, in base al quale esiste una funzione chiamata db(dbname)che è necessario richiamare per ottenere l' dbistanza che si sta cercando.

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
Questa risposta è più recente e si applica alla versione 3 del driver. Grazie
Mohammad,

1
Raccomando questa soluzione, è più appropriato per riferimento futuro.
Jamie Nicholl-Shelley il

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

L'unico problema con il codice è che si sta accedendo all'oggetto che contiene il gestore database. È necessario accedere direttamente al database (vedere la variabile del database sopra). Questo codice restituirà il database in un array, quindi lo attraverserà e registrerà il nome per tutti nel database.


Questa risposta è contrassegnata come di bassa qualità a causa della sua lunghezza e contenuto. Si prega di fornire ulteriori informazioni.
Wahyu Kristianto,

È solo il tempo necessario. Questa risposta mi ha aiutato.
Manuel Hernandez,

1
@ManuelHernandez felice di aver aiutato :)
Dre Jackson

questa è la risposta corretta Si prega di contrassegnare questo come un ans corretto.
Ninad Kambli il

12

A sostegno della risposta di @MikkaS per Mongo Client v3.x, avevo solo bisogno del formato asincrono / wait, che appare leggermente modificato come questo:

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

Ho fatto un piccolo esperimento per vedere se potevo mantenere il nome del database come parte dell'URL. Preferisco la sintassi promessa, ma dovrebbe comunque funzionare per la sintassi di callback. Si noti che client.db () viene chiamato senza passare alcun parametro.

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

Il mio pacchetto.json elenca monbodb ^ 3.2.5.

L'opzione "useNewUrlParser" non è necessaria se si è disposti a gestire un avviso di ammortamento. Ma è saggio usarlo a questo punto fino a quando non uscirà la versione 4 dove presumibilmente il nuovo driver sarà quello predefinito e non avrai più bisogno dell'opzione.


5

L'ho risolto facilmente eseguendo questi codici:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Buona programmazione!


4

Ho MongoDB versione shell v3.6.4, sotto il codice uso mongoclient, è buono per me:

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

Questa domanda riguarda il driver del nodo, non la shell.
UpTheCreek,

3

Se qualcuno sta ancora cercando di risolvere questo errore, l'ho fatto come di seguito.

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

Questa soluzione e quella di @Dre Jackson sono quelle che funzionano con il nodo a partire dal 07/2020. Sembra che ciò che viene passato come argomento al callback di connessione sia MongoClient piuttosto che un db, motivo per cui è necessario recuperare il db da esso. Oltre a ciò, questa soluzione elenca anche useUnifiedTopology: true, che è anche necessario al giorno d'oggi.
Coffee_fan

1

Le query MongoDB restituiscono un cursore su un array memorizzato. Per accedere al risultato di quell'array è necessario chiamare .toArray()alla fine della query.

  db.collection("customers").find({}).toArray() 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.