Node.js 如何使用nodeJS MongoClient按顺序打印数据库名称及其集合名称?
我正在尝试使用MongoDB Node.js驱动程序的嵌套循环打印数据库名称列表及其对应的集合名称 数据库A: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(
集合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确实有效。