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 install 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
Эли Асмар

Затем замените код, который начинается db.collection()...с журнала консоли, чтобы увидеть, попадает ли он туда, нет проблем.
nbkhope 05

База данных и коллекция существуют (я получил к ним доступ с помощью Studio 3t). Я отлаживаю nodeJS, вызывая метод через вызов AJAX, в основном достигаются точки останова, и все работает нормально, пока я не получу исключение, указанное выше. Версия NodeJS
Эли Асмар

Ответы:


79

Я столкнулся с тем же самым. В package.json измените строку mongodb на «mongodb»: «^ 2.2.33». Вам нужно будет удалить mongodb с помощью npm; затем npm install, чтобы установить эту версию.

Это решило проблему для меня. Кажется, это ошибка или необходимо обновить документы.


15
проверьте ответ
MikaS

67
переход на более раннюю версию на самом деле не является решением, это просто означает, что вы не удосужились
изучить

3
@JohnCulviner - Это была проблема времени; не проблема лени. Эта проблема возникла, когда они были в процессе выпуска нового обновления. Я (и исходный постер) явно этого не осознавал. На тот момент документы еще не обновлялись. Они были обновлены вскоре после этого. Любой, кто хочет решить эту проблему на данный момент, должен следить за комментарием MikaS и просматривать обновленные документы. Я сделал то же самое после обновления документов и смог продолжить работу с обновленной версией.
AyoO 02

1
Столкнувшись с этим сейчас - я столкнулся с этой проблемой и установил «mongodb:» «3.0.2» в package.json, есть ли проблемы с новой версией?
logos_164

4
Совсем не помогает. Почему он отмечен как правильный ответ?
CodingNow

484

Для пользователей версии 3.0 собственного драйвера NodeJS MongoDB:

(Это применимо к людям с "mongodb": "^ 3.0.0-rc0" или более поздней версией в package.json, которые хотят продолжать использовать последнюю версию.)

В версии 2.x собственного драйвера NodeJS MongoDB вы получите объект базы данных в качестве аргумента для обратного вызова подключения:

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');каждый раз писать эту ( ) дополнительную строку вместо того, чтобы просто писать как this ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? Я всегда работаю с одной и той же базой данных. Есть ли способ устранить эту лишнюю строку? Для меня это отнимает много времени.
ozgrozer

7
@ozgrozer Мне кажется, вы подключаетесь к базе данных для каждого запроса. Это считается плохой идеей. Вы можете прочитать об этом здесь . Если вы подключаетесь только один раз, для каждого создаваемого приложения будет только одна новая строка.
Мика Сундленд

1
@MikaS О да. Я подключался к БД, как вы сказали. Я не знал, что мы можем подключиться один раз и повторно использовать переменную db. Огромное спасибо.
ozgrozer

1
Отличный ответ; выяснение этого было
отстойным

Я реализовал клиент таким образом, но все еще остаются те же проблемы (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 драйвера. Спасибо
Мохаммад

1
Я рекомендую это решение, оно больше подходит для использования в будущем.
Джейми Николл-Шелли

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

Это ровно столько, сколько нужно. Этот ответ мне помог.
Мануэль Эрнандес

1
@ManuelHernandez рад, что это помогло :)
Dre Jackson

это правильный ответ. Отметьте это как правильный ответ.
Нинад Камбли,

12

Копилка для ответа @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

Удачного кодирования!


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 работают с node по состоянию на 07/2020. Похоже, что то, что передается в качестве аргумента обратному вызову подключения, - это MongoClient, а не база данных, поэтому вам нужно получить из нее базу данных. Помимо этого, в этом решении также перечислены те useUnifiedTopology: true, которые необходимы и сегодня.
Coffee_fan

1

Запросы MongoDB возвращают курсор в массив, хранящийся в памяти. Чтобы получить доступ к результату этого массива, вы должны вызвать его .toArray()в конце запроса.

  db.collection("customers").find({}).toArray() 
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.