Node.js 如何使用nodeJS MongoClient按顺序打印数据库名称及其集合名称?

Node.js 如何使用nodeJS MongoClient按顺序打印数据库名称及其集合名称?,node.js,mongodb,Node.js,Mongodb,我正在尝试使用MongoDB Node.js驱动程序的嵌套循环打印数据库名称列表及其对应的集合名称 数据库A: 集合a 集合b 数据库B: 集合f 集合g 数据库C: 集合h 集合j 但我得到的却是: 数据库A: 数据库B: 数据库C: 集合a 集合b 集合f 集合g 集合h 集合j 我做错了什么?这是因为listDatabases()和listCollections()共享同一个MongoClient连接,不能同时执行,还是因为promise的原因 const mongo = require(

我正在尝试使用MongoDB Node.js驱动程序的嵌套循环打印数据库名称列表及其对应的集合名称

数据库A:
集合a
集合b
数据库B:
集合f
集合g
数据库C:
集合h
集合j

但我得到的却是:
数据库A:
数据库B:
数据库C:
集合a
集合b
集合f
集合g
集合h
集合j

我做错了什么?这是因为
listDatabases()
listCollections()
共享同一个MongoClient连接,不能同时执行,还是因为
promise
的原因

const mongo = require('mongodb').MongoClient;

const url = 'mongodb://127.0.0.1:27017';

mongo.connect(url, {
    useNewUrlParser: true,
    useUnifiedTopology: true
}, (err, client) => {
    if (err) {
        console.log(err)
        return;
    }
    // print db names with their corresponding collections
    client.db().admin().listDatabases({ nameOnly: true }, (err, result) => {
        if (!err) {
            result.databases.forEach((db) => {
                console.log('Database: ' + db.name);

                client.db(db.name).listCollections().toArray((err, collections) => {
                    collections.forEach((col) => {
                        console.log(col.name);
                    });
                });

            });
        } else {
            return console.log(err.message);
        }
    });
});

尝试将其转换为promise,并使用映射异步等待结果
因此可能是有帮助的

这是因为
client.db(db.name).listCollections()是
异步的
操作。简单地说,
result.databases.forEach
不会等待上面刚刚打印的当前数据库的每个集合列表。从输出中可以明显看出这一点

// print db names with their corresponding collections
client
  .db("test")
  .admin()
  .listDatabases({ nameOnly: true }, (err, results) => {
    if (err) {
      return console.error("Error::", err.message);
    }
    results.databases.forEach((item, index) => {
      client
        .db(item.name)
        .listCollections()
        .toArray((err, collections) => {
          if (err) {
            return console.error("Error::", err.message);
          }
          console.info("DATABASE: ", item.name);
          collections.forEach(col => {
            console.info("COLLECTION: ", col.name);
          });
        });
    });
  });
这就是使用
async
操作的回调的行为方式。使用
async/await
promise/then
语法可以使它看起来更美观。如果坚持回调语法,只需将db控制台移到内部即可实现输出

// print db names with their corresponding collections
client
  .db("test")
  .admin()
  .listDatabases({ nameOnly: true }, (err, results) => {
    if (err) {
      return console.error("Error::", err.message);
    }
    results.databases.forEach((item, index) => {
      client
        .db(item.name)
        .listCollections()
        .toArray((err, collections) => {
          if (err) {
            return console.error("Error::", err.message);
          }
          console.info("DATABASE: ", item.name);
          collections.forEach(col => {
            console.info("COLLECTION: ", col.name);
          });
        });
    });
  });
更新:使用
async/await
syntax

const MongoClient = require("mongodb").MongoClient;
const url = "mongodb://localhost:27017";
const client = new MongoClient(url, {
  useNewUrlParser: true,
  useUnifiedTopology: true
});
const defaultDb = "test";

(async function() {
  try {
    await client.connect();
    //fetching dbs
    const dbs = await client
      .db(defaultDb)
      .admin()
      .listDatabases({ nameOnly: true });

    for (db of dbs.databases) {
      console.info("Database::", db.name);
      const collections = await client
        .db(db.name)
        .listCollections()
        .toArray();

      for (c of collections) {
        console.info("Collection::", c.name);
      }
    }
    client.close();
  } catch (err) {
    console.log(err.stack);
  }
})();

请注意
for..of
语法与
await
的区别,因为
forEach
的行为方式与预期不同。(让i=0…i++)
的普通
也可以与
wait

转换什么..?我很抱歉,还不清楚。获取数据库列表并将其保存在数组中。然后使用map对它们进行循环以获取它们的集合。您需要在map中使用async/await,以便检查链接
dbName
是db()的可选参数。是的!仅供参考,
mongodb@3.3.1
(我在上)情况并非如此,但对于目前最新的
V3.3.3
dbName
optionality确实有效。