db.collection không phải là một chức năng khi sử dụng MongoClient v3.0


132

Tôi đã thử hướng dẫn W3schools trên nodeJS với MongoDB.

Khi tôi cố gắng thực hiện ví dụ này trong môi trường nodeJS và gọi hàm bằng lệnh gọi AJAX, tôi đã gặp lỗi dưới đây:

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)

Vui lòng tìm bên dưới mã thực hiện của tôi:

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

Lưu ý rằng lỗi xảy ra bất cứ khi nào thực thi xảy ra:

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

Ngoài ra, lưu ý (trong trường hợp có vấn đề) rằng tôi đã cài đặt gói MongoDB mới nhất cho nút JS ( npm install mongodb ) và phiên bản MongoDB là MongoDB Enterprise 3.4.4, với trình điều khiển MongoDB Node.js v3.0.0-rc0.


Bạn có chắc chắn: (1) cơ sở dữ liệu đang chạy (do không có lỗi, tôi đoán vậy); (2) cơ sở dữ liệu mytestingdb tồn tại (thử sử dụng robomongo / robo3t để truy cập kết nối của bạn và xem các bộ sưu tập) (3) Bộ sưu tập khách hàng thực sự tồn tại; Đồng thời cho chúng tôi biết bạn đang gọi tập lệnh đó như thế nào và phiên bản nào của Nodejs (bạn đã cài đặt như thế nào?)
nbkhope

Cơ sở dữ liệu và bộ sưu tập tồn tại (Tôi đã truy cập chúng bằng Studio 3t). Tôi đang gỡ lỗi nodeJS bằng cách gọi phương thức thông qua một cuộc gọi AJAX, về cơ bản các điểm dừng đang bị tấn công và mọi thứ đều hoạt động tốt cho đến khi tôi nhận được ngoại lệ được nêu ở trên. Phiên bản NodeJS là v6.11.4
Elie Asmar

Sau đó thay thế mã bắt đầu bằng db.collection()...nhật ký giao diện điều khiển để xem nếu nó ở đó, không có vấn đề gì.
nbkhope

Cơ sở dữ liệu và bộ sưu tập tồn tại (Tôi đã truy cập chúng bằng Studio 3t). Tôi đang gỡ lỗi nodeJS bằng cách gọi phương thức thông qua một cuộc gọi AJAX, về cơ bản các điểm dừng đang bị tấn công và mọi thứ đều hoạt động tốt cho đến khi tôi nhận được ngoại lệ được nêu ở trên. Phiên bản NodeJS là v6.11.4
Elie Asmar

Bản sao có thể có của stackoverflow.com/questions/43779323/
Thẻ

Câu trả lời:


80

Tôi gặp phải điều tương tự. Trong gói.json, thay đổi dòng mongodb thành "mongodb": "^ 2.2.33". Bạn sẽ cần npm gỡ cài đặt mongodb; sau đó cài đặt npm để cài đặt phiên bản này.

Điều này giải quyết vấn đề cho tôi. Có vẻ là một lỗi hoặc tài liệu cần phải được cập nhật.


15
kiểm tra câu trả lời của
MikaS

67
hạ cấp xuống phiên bản cũ hơn thực sự không phải là một giải pháp, điều đó chỉ có nghĩa là bạn không bận tâm đến việc thay đổi API gây ra điều này
John Culviner

3
@JohnCulviner - Đây là một vấn đề thời gian; không phải là một vấn đề lười biếng Vấn đề này xảy ra trong khi họ đang trong quá trình phát hành bản cập nhật mới. Tôi (và người đăng ban đầu) rõ ràng không nhận ra điều này. Vào thời điểm đó, các tài liệu chưa được cập nhật. Chúng đã được cập nhật ngay sau đó. Bất cứ ai đang tìm cách giải quyết vấn đề này nên theo dõi nhận xét của MikaS và xem xét các tài liệu đã cập nhật .. Tôi cũng làm như vậy sau khi các tài liệu được cập nhật và có thể tiếp tục với phiên bản nâng cấp.
AyoO

1
Gặp phải vấn đề này ngay bây giờ - Tôi đang gặp phải vấn đề này và đã cài đặt "mongodb:" "3.0.2" trong gói.json, có vấn đề gì với phiên bản mới không?
logo_164

4
Không giúp được gì cả. Tại sao nó được gắn cờ là câu trả lời đúng?
Mã hóa

481

Dành cho mọi người trên phiên bản 3.0 của trình điều khiển NodeJS gốc MongoDB:

(Điều này có thể áp dụng cho những người có "mongodb": "^ 3.0.0-rc0" hoặc phiên bản mới hơn trong gói.json, muốn tiếp tục sử dụng phiên bản mới nhất.)

Trong phiên bản 2.x của trình điều khiển NodeJS gốc MongoDB, bạn sẽ lấy đối tượng cơ sở dữ liệu làm đối số cho cuộc gọi lại kết nối:

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

Theo thay đổi cho 3.0, bây giờ bạn có một đối tượng máy khách chứa đối tượng cơ sở dữ liệu thay thế:

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

Các close()phương pháp cũng đã được chuyển cho khách hàng. Do đó, mã trong câu hỏi có thể được dịch thành:

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

Bây giờ chúng ta phải viết var db = client.db('mytestingdb');thêm dòng này ( ) mỗi lần thay vì chỉ viết như thế này ( MongoClient.connect('mongodb://localhost:27017/mytestingdb'))? Tôi luôn làm việc với cùng một cơ sở dữ liệu. Có cách tiếp cận nào để loại bỏ dòng bổ sung đó không? Nó giống như việc tiêu tốn thời gian của tôi.
ozgrozer

7
@ozgrozer Âm thanh với tôi như bạn đang kết nối với db cho mọi yêu cầu. Đó là một ý tưởng tồi. Bạn có thể đọc về nó ở đây . Nếu bạn chỉ kết nối một lần thì chỉ có một dòng mới cho mỗi ứng dụng bạn tạo.
Mika Sundland

1
@MikaS Ồ vâng. Tôi đã kết nối với db như bạn nói. Tôi không biết rằng chúng ta có thể kết nối một lần và sử dụng lại biến db. Cảm ơn bạn rất nhiều.
ozgrozer

1
Câu trả lời chính xác; hình dung ra điều này là một mút thời gian, tôi nên nhớ đến RTFM
Mr.Budris

Tôi đã thực hiện cho khách hàng như vậy, nhưng vẫn còn những vấn đề tương tự (db.collection không phải là một chức năng) bên trong \ node_modules \ MongoDB \ lib \ gridfs dòng \ index.js: 50: 27
alex351

33

Đối với những người muốn tiếp tục sử dụng phiên bản ^ 3.0.1, hãy lưu ý đến những thay đổi đối với cách bạn sử dụng MongoClient.connect()phương pháp. Cuộc gọi lại không trả về dbthay vào đó nó trả về client, dựa vào đó có một hàm được gọi là db(dbname)bạn phải gọi để lấy dbphiên bản mà bạn đang tìm kiếm.

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
Câu trả lời này gần đây hơn và áp dụng cho phiên bản 3 của trình điều khiển. Cảm ơn
Mohammad

1
Tôi đề nghị giải pháp này, nó phù hợp hơn để tham khảo trong tương lai.
Jamie Nicholl-Shelley

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

Vấn đề duy nhất với mã của bạn là bạn đang truy cập vào đối tượng đang xử lý cơ sở dữ liệu. Bạn phải truy cập cơ sở dữ liệu trực tiếp (xem biến cơ sở dữ liệu ở trên). Mã này sẽ trả về cơ sở dữ liệu của bạn trong một mảng và sau đó nó lặp qua nó và ghi lại tên cho mọi người trong cơ sở dữ liệu.


Câu trả lời này được đánh dấu là chất lượng thấp vì độ dài và nội dung của nó. Vui lòng cung cấp thêm thông tin.
Wahyu Kristianto

Nó chỉ miễn là nó cần phải được. Câu trả lời này đã giúp tôi.
Manuel Hernandez

1
@ManuelHernandez rất vui vì nó đã giúp :)
Dre Jackson

đây là ans chính xác. Vui lòng đánh dấu đây là một ans chính xác.
Ninad Kambli

12

Piggy ủng hộ câu trả lời @MikkaS cho Mongo Client v3.x, tôi chỉ cần định dạng async / await, có vẻ hơi được sửa đổi như sau:

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

Tôi đã làm một thử nghiệm nhỏ để xem liệu tôi có thể giữ tên cơ sở dữ liệu như một phần của url không. Tôi thích cú pháp lời hứa nhưng nó vẫn hoạt động cho cú pháp gọi lại. Lưu ý bên dưới rằng client.db () được gọi mà không truyền bất kỳ tham số nào.

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

Gói.json của tôi liệt kê monbodb ^ 3.2.5.

Tùy chọn 'useNewUrlParser' là không bắt buộc nếu bạn sẵn sàng đối phó với cảnh báo không dùng nữa. Nhưng nên sử dụng vào thời điểm này cho đến khi phiên bản 4 xuất hiện trong đó có lẽ trình điều khiển mới sẽ là mặc định và bạn sẽ không cần tùy chọn này nữa.


5

Tôi đã giải quyết nó dễ dàng thông qua việc chạy các mã này:

 npm uninstall mongodb --save

 npm install mongodb@2.2.33 --save

Chúc mừng mã hóa!


4

Tôi có phiên bản shell MongoDB v3.6.4, bên dưới mã sử dụng mongoclient, Nó tốt cho tôi:

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

Câu hỏi này liên quan đến trình điều khiển nút, không phải trình bao.
UpTheCux

2

Nếu ai đó vẫn đang cố gắng giải quyết lỗi này, tôi đã thực hiện việc này như dưới đây.

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

1

Các truy vấn MongoDB trả về một con trỏ tới một mảng được lưu trong bộ nhớ. Để truy cập kết quả của mảng đó, bạn phải gọi .toArray()ở cuối truy vấn.

  db.collection("customers").find({}).toArray() 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.