db.collection n'est pas une fonction lors de l'utilisation de MongoClient v3.0

132

J'ai essayé le tutoriel W3schools sur nodeJS avec MongoDB.

Lorsque j'essaie d'implémenter cet exemple dans un environnement nodeJS et d'appeler la fonction avec un appel AJAX, j'ai l'erreur ci-dessous:

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)

Veuillez trouver ci-dessous mon code implémenté:

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

Notez que l'erreur se produit chaque fois que l'exécution se produit:

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

Notez également (au cas où cela importe) que j'ai installé le dernier package MongoDB pour le nœud JS ( npm install mongodb ), et que la version MongoDB est MongoDB Enterprise 3.4.4, avec le pilote MongoDB Node.js v3.0.0-rc0.

Elie Asmar
la source
Vous êtes-vous assuré que: (1) la base de données est en cours d'exécution (étant donné qu'il n'y a pas eu d'erreur, je suppose); (2) la base de données mytestingdb existe (essayez d'utiliser robomongo / robo3t pour accéder à votre connexion et voir les collections) (3) La collection clients existe réellement; Dites-nous également comment vous appelez ce script et quelle version de Nodejs (comment avez-vous installé?)
nbkhope
La base de données et la collection existent (je les ai accédées avec Studio 3t). Je débogue nodeJS en appelant la méthode via un appel AJAX, essentiellement les points d'arrêt sont atteints et tout fonctionne bien jusqu'à ce que j'obtienne l'exception indiquée ci-dessus. La version NodeJS est v6.11.4
Elie Asmar
Remplacez ensuite le code qui commence par db.collection()...un journal de console pour voir s'il y arrive, pas de problème.
nbkhope
La base de données et la collection existent (je les ai accédées avec Studio 3t). Je débogue nodeJS en appelant la méthode via un appel AJAX, essentiellement les points d'arrêt sont atteints et tout fonctionne bien jusqu'à ce que j'obtienne l'exception indiquée ci-dessus. La version NodeJS est v6.11.4
Elie Asmar

Réponses:

80

J'ai rencontré la même chose. Dans package.json, remplacez la ligne mongodb par "mongodb": "^ 2.2.33". Vous devrez désinstaller npm mongodb; puis npm install pour installer cette version.

Cela a résolu le problème pour moi. Semble être un bogue ou les documents doivent être mis à jour.

AyoO
la source
15
vérifier la réponse de
MikaS
67
la rétrogradation à une version antérieure n'est pas vraiment une solution, cela signifie simplement que vous n'avez pas pris la peine de regarder les modifications de l'API qui en ont causé
John Culviner
3
@JohnCulviner - C'était un problème de timing; pas un problème de paresse. Ce problème s'est produit alors qu'ils étaient en train de publier la nouvelle mise à jour. Je ne m'en suis évidemment pas rendu compte (ainsi que l'affiche originale). À cette époque, les documents n'étaient pas encore mis à jour. Ils ont été mis à jour peu de temps après. Quiconque cherche à résoudre ce problème à partir de maintenant devrait suivre le commentaire de MikaS et examiner les documents mis à jour. J'ai fait de même après la mise à jour des documents et j'ai pu continuer avec la version mise à jour.
AyoO
1
En rencontrant ceci maintenant - je rencontrais ce problème et j'avais le "mongodb:" "3.0.2" installé dans package.json, y a-t-il des problèmes avec la nouvelle version?
logos_164
4
Ça n'aide pas du tout. Pourquoi est-il signalé comme la bonne réponse?
CodingNow
482

Pour les utilisateurs de la version 3.0 du pilote NodeJS natif MongoDB:

(Cela s'applique aux personnes avec "mongodb": "^ 3.0.0-rc0", ou une version ultérieure de package.json, qui souhaitent continuer à utiliser la dernière version.)

Dans la version 2.x du pilote NodeJS natif MongoDB, vous obtiendrez l'objet de base de données comme argument du rappel de connexion:

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

Selon le changelog pour 3.0, vous obtenez maintenant un objet client contenant l'objet de base de données à la place:

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

La close()méthode a également été déplacée vers le client. Le code de la question peut donc être traduit en:

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
la source
Maintenant, devons-nous écrire cette ( var db = client.db('mytestingdb');) ligne supplémentaire à chaque fois au lieu d'écrire simplement comme ceci ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? Je travaille toujours avec la même base de données. Existe-t-il une approche pour éliminer cette ligne supplémentaire? C'est un peu comme une chose qui prend du temps pour moi.
ozgrozer
7
@ozgrozer Il me semble que vous vous connectez à la base de données pour chaque demande. C'est considéré comme une mauvaise idée. Vous pouvez en savoir plus ici . Si vous ne vous connectez qu'une seule fois, il n'y a qu'une seule nouvelle ligne par application que vous créez.
Mika Sundland
1
@MikaS Oh oui. Je me connectais à la base de données comme tu l'as dit. Je ne savais pas que nous pouvions nous connecter une fois et réutiliser la variable db. Merci beaucoup.
ozgrozer
1
Très bonne réponse; comprendre que c'était un temps nul, je devrais me rappeler de RTFM
Mr.Budris
J'ai implémenté le client comme tel, mais il y a toujours les mêmes problèmes (db.collection n'est pas une fonction) à l'intérieur de \ node_modules \ mongodb \ lib \ gridfs-stream \ index.js: 50: 27
alex351
34

Pour ceux qui souhaitent continuer à utiliser la version ^ 3.0.1, tenez compte des modifications apportées à la façon dont vous utilisez la MongoClient.connect()méthode. Le rappel ne retourne pas à la dbplace, il retourne client, contre lequel il y a une fonction appelée db(dbname)que vous devez appeler pour obtenir l' dbinstance que vous recherchez.

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
la source
2
Cette réponse est plus récente et s'applique à la version 3 du pilote. Merci
Mohammad
1
Je recommande cette solution, elle est plus appropriée pour référence future.
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);
        });
    })
})

Le seul problème avec votre code est que vous accédez à l'objet contenant le gestionnaire de base de données. Vous devez accéder directement à la base de données (voir la variable de base de données ci-dessus). Ce code renverra votre base de données dans un tableau, puis il la boucle et enregistre le nom de tout le monde dans la base de données.

Dre Jackson
la source
Cette réponse est considérée comme de mauvaise qualité en raison de sa longueur et de son contenu. Veuillez fournir plus d'informations.
Wahyu Kristianto
C'est seulement aussi longtemps que nécessaire. Cette réponse m'a aidé.
Manuel Hernandez le
1
@ManuelHernandez heureux que cela ait aidé :)
Dre Jackson
ce sont les bons ans. Veuillez marquer ceci comme un ans correct.
Ninad Kambli
12

Piggy backing sur la réponse @MikkaS pour Mongo Client v3.x, j'avais juste besoin du format async / await, qui semble légèrement modifié comme ceci:

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.
}
agarcien
la source
7

J'ai fait un peu d'expérimentation pour voir si je pouvais garder le nom de la base de données dans le cadre de l'URL. Je préfère la syntaxe de promesse mais cela devrait toujours fonctionner pour la syntaxe de rappel. Notez ci-dessous que client.db () est appelé sans passer aucun paramètre.

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

Mon package.json répertorie monbodb ^ 3.2.5.

L'option 'useNewUrlParser' n'est pas requise si vous êtes prêt à gérer un avertissement d'obsolescence. Mais il est sage d'utiliser à ce stade jusqu'à ce que la version 4 sorte où vraisemblablement le nouveau pilote sera le pilote par défaut et vous n'aurez plus besoin de l'option.

pwilcox
la source
5

Je l'ai résolu facilement en exécutant ces codes:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Bon codage!

Saurabh Singh
la source
4

J'ai la version de shell MongoDB v3.6.4, ci-dessous le code utilise mongoclient, c'est bon pour moi:

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
la source
Cette question concerne le pilote du nœud, pas le shell.
UpTheCreek
3

Si quelqu'un essaie toujours de résoudre cette erreur, je l'ai fait comme ci-dessous.

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
la source
Cette solution et celle de @Dre Jackson sont celles qui fonctionnent avec node à partir de 07/2020. On dirait que ce qui est passé comme argument au rappel de connexion est le MongoClient plutôt qu'une base de données, c'est pourquoi vous devez en extraire la base de données. En dehors de cela, cette solution répertorie également le useUnifiedTopology: true, qui est également nécessaire de nos jours.
Coffee_fan il y a
1

Les requêtes MongoDB renvoient un curseur sur un tableau stocké en mémoire. Pour accéder au résultat de ce tableau, vous devez appeler .toArray()à la fin de la requête.

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