NodeJS/Mongo:通过各种 collections 循环查询
NodeJS/Mongo: Looping a query through various collections
我希望使用 NodeJS Driver 通过 collection 和 MongoDB 循环查询。
对于此测试,我使用 sample code from the 'findOne' docs 在各种 Collection 中插入一堆文档:
collection.insertMany([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}, function(err, result) {
test.equal(null, err);
同时创建各种 collections(每个 collection 至少有一个先前插入的文档实例):
- 测试
- 测试1
- 测试2
- 测试3
- 测试4
- test6
- 测试10
我想要的是收集我在数据库中的 collection 列表(在我的例子中是 'test'
):
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
console.log(items);
db.close();
});
});
然后弹出前面提到的 collection 列表。到目前为止,一切都是all-right!我什至可以遍历数组以仅获取 collection 的名称:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
console.log(c.name);
});
db.close();
});
});
再次没问题!但是当我在循环中尝试查询时:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
var collection = db.collection(c.name);
collection.findOne({ a: 2 }, { fields: { b: 1 } }, function(err, doc) {
console.log(doc);
});
});
});
db.close();
});
我得到:
null
null
null
null
null
null
null
尽管循环获取 collection 似乎工作得很好:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
var collection = db.collection(c.name);
console.log(collection);
});
});
db.close();
});
示例输出:
Collection {
s:
{ pkFactory:
{ [Function: ObjectID]
index: 10866728,
createPk: [Function: createPk],
createFromTime: [Function: createFromTime],
createFromHexString: [Function: createFromHexString],
isValid: [Function: isValid],
ObjectID: [Circular],
ObjectId: [Circular] },
db:
Db {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
s: [Object],
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter] },
topology:
Server {
domain: null,
_events: [Object],
_eventsCount: 8,
_maxListeners: undefined,
clientInfo: [Object],
s: [Object] },
dbName: 'test',
options:
{ promiseLibrary: [Function: Promise],
readConcern: undefined,
readPreference: [Object] },
namespace: 'test.test2',
readPreference:
ReadPreference {
_type: 'ReadPreference',
mode: 'primary',
tags: undefined,
options: undefined },
slaveOk: true,
serializeFunctions: undefined,
raw: undefined,
promoteLongs: undefined,
promoteValues: undefined,
promoteBuffers: undefined,
internalHint: null,
collectionHint: null,
name: 'test2',
promiseLibrary: [Function: Promise],
readConcern: undefined } }
我猜 Collection
结构是我循环的问题,但我不确定到底发生了什么......
这是每个 Collection 的预期输出示例:
{ _id: 5a13de85a55e615235f71528, b: 2 }
如有任何帮助,我们将不胜感激!提前致谢!
javaScript 中的 ForEach 循环是同步的,直到它不包含任何异步调用。在这种情况下,您不能在 for 循环中调用任何数据库调用。
相反,您可以使用一个名为 async 的库,它带有一些很棒的函数来解决这个问题,如下所示
var MongoClient = require("mongodb").MongoClient,
test = require("assert"),
async = require('async');
MongoClient.connect("mongodb://localhost:27017/test", function (err, db) {
db.listCollections().toArray(function (err, items) {
test.ok(items.length >= 1);
async.map(items, (each, callback) => {
let collection = db.collection(each.name);
collection.findOne({a: 2}, {fields: {b: 1}}, function (err, doc) {
console.log(doc);
callback();
});
}, (err) => {
console.log("done");
});
});
db.close();
});
虽然这不是最好的语法并且除了记录输出外没有用,但这对我有用:
var mongodb = require('mongodb');
mongodb.connect('mongodb://localhost:27017/test', function (err, db) {
if (err) {
throw err;
}
db.listCollections().toArray(function (err, cols) {
if (err) {
throw err;
}
cols.forEach(function (col) {
db.collection(col.name).find({}, {}, 0, 1, function (err, docs) {
if(err){
throw err;
}
console.log(col);
docs.forEach(console.log);
});
});
})
})
所以,也许查询条件不匹配?
此外,使用 Promises 会更好:
const mongodb = require('mongodb');
const Promise = require('bluebird');
function getDb() {
return Promise.resolve(mongodb.connect('mongodb://localhost:27017/test'));
}
function getCollections(db) {
return Promise.resolve(db.listCollections().toArray());
}
function getDocs(db, col) {
return Promise.resolve(db.collection(col.name).find({},{},0,1).toArray());
}
const data = {};
getDb()
.then((db) => {
data.db = db;
return getCollections(db);
}).then((cols) => {
data.cols = cols;
return Promise.map(cols, (col) => getDocs(data.db,col));
}).then((docs) => {
console.log(docs);
})
我希望使用 NodeJS Driver 通过 collection 和 MongoDB 循环查询。 对于此测试,我使用 sample code from the 'findOne' docs 在各种 Collection 中插入一堆文档:
collection.insertMany([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}, function(err, result) {
test.equal(null, err);
同时创建各种 collections(每个 collection 至少有一个先前插入的文档实例):
- 测试
- 测试1
- 测试2
- 测试3
- 测试4
- test6
- 测试10
我想要的是收集我在数据库中的 collection 列表(在我的例子中是 'test'
):
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
console.log(items);
db.close();
});
});
然后弹出前面提到的 collection 列表。到目前为止,一切都是all-right!我什至可以遍历数组以仅获取 collection 的名称:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
console.log(c.name);
});
db.close();
});
});
再次没问题!但是当我在循环中尝试查询时:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
var collection = db.collection(c.name);
collection.findOne({ a: 2 }, { fields: { b: 1 } }, function(err, doc) {
console.log(doc);
});
});
});
db.close();
});
我得到:
null
null
null
null
null
null
null
尽管循环获取 collection 似乎工作得很好:
var MongoClient = require("mongodb").MongoClient,
test = require("assert");
MongoClient.connect("mongodb://localhost:27017/test", function(err, db) {
db.listCollections().toArray(function(err, items) {
test.ok(items.length >= 1);
items.forEach(c => {
var collection = db.collection(c.name);
console.log(collection);
});
});
db.close();
});
示例输出:
Collection {
s:
{ pkFactory:
{ [Function: ObjectID]
index: 10866728,
createPk: [Function: createPk],
createFromTime: [Function: createFromTime],
createFromHexString: [Function: createFromHexString],
isValid: [Function: isValid],
ObjectID: [Circular],
ObjectId: [Circular] },
db:
Db {
domain: null,
_events: {},
_eventsCount: 0,
_maxListeners: undefined,
s: [Object],
serverConfig: [Getter],
bufferMaxEntries: [Getter],
databaseName: [Getter] },
topology:
Server {
domain: null,
_events: [Object],
_eventsCount: 8,
_maxListeners: undefined,
clientInfo: [Object],
s: [Object] },
dbName: 'test',
options:
{ promiseLibrary: [Function: Promise],
readConcern: undefined,
readPreference: [Object] },
namespace: 'test.test2',
readPreference:
ReadPreference {
_type: 'ReadPreference',
mode: 'primary',
tags: undefined,
options: undefined },
slaveOk: true,
serializeFunctions: undefined,
raw: undefined,
promoteLongs: undefined,
promoteValues: undefined,
promoteBuffers: undefined,
internalHint: null,
collectionHint: null,
name: 'test2',
promiseLibrary: [Function: Promise],
readConcern: undefined } }
我猜 Collection
结构是我循环的问题,但我不确定到底发生了什么......
这是每个 Collection 的预期输出示例:
{ _id: 5a13de85a55e615235f71528, b: 2 }
如有任何帮助,我们将不胜感激!提前致谢!
javaScript 中的 ForEach 循环是同步的,直到它不包含任何异步调用。在这种情况下,您不能在 for 循环中调用任何数据库调用。
相反,您可以使用一个名为 async 的库,它带有一些很棒的函数来解决这个问题,如下所示
var MongoClient = require("mongodb").MongoClient,
test = require("assert"),
async = require('async');
MongoClient.connect("mongodb://localhost:27017/test", function (err, db) {
db.listCollections().toArray(function (err, items) {
test.ok(items.length >= 1);
async.map(items, (each, callback) => {
let collection = db.collection(each.name);
collection.findOne({a: 2}, {fields: {b: 1}}, function (err, doc) {
console.log(doc);
callback();
});
}, (err) => {
console.log("done");
});
});
db.close();
});
虽然这不是最好的语法并且除了记录输出外没有用,但这对我有用:
var mongodb = require('mongodb');
mongodb.connect('mongodb://localhost:27017/test', function (err, db) {
if (err) {
throw err;
}
db.listCollections().toArray(function (err, cols) {
if (err) {
throw err;
}
cols.forEach(function (col) {
db.collection(col.name).find({}, {}, 0, 1, function (err, docs) {
if(err){
throw err;
}
console.log(col);
docs.forEach(console.log);
});
});
})
})
所以,也许查询条件不匹配?
此外,使用 Promises 会更好:
const mongodb = require('mongodb');
const Promise = require('bluebird');
function getDb() {
return Promise.resolve(mongodb.connect('mongodb://localhost:27017/test'));
}
function getCollections(db) {
return Promise.resolve(db.listCollections().toArray());
}
function getDocs(db, col) {
return Promise.resolve(db.collection(col.name).find({},{},0,1).toArray());
}
const data = {};
getDb()
.then((db) => {
data.db = db;
return getCollections(db);
}).then((cols) => {
data.cols = cols;
return Promise.map(cols, (col) => getDocs(data.db,col));
}).then((docs) => {
console.log(docs);
})