代码之家  ›  专栏  ›  技术社区  ›  Martin Carre

NodeJS/Mongo:在各种集合中循环查询

  •  6
  • Martin Carre  · 技术社区  · 8 年前

    我希望通过MongoDB使用 NodeJS Driver . 在这个测试中,我使用了 sample code from the 'findOne' docs 要在各种集合中插入一组文档,请执行以下操作:

      collection.insertMany([{a:1, b:1}, {a:2, b:2}, {a:3, b:3}], {w:1}, function(err, result) {
        test.equal(null, err);
    

    同时创建各种集合(每个集合至少有一个先前插入的文档实例):

    • 测验
    • 测试1
    • 测试2
    • 测试3
    • 测试4
    • 测试6
    • 测试10

    我想要的是收集数据库中的集合列表( '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();
      });
    });
    

    然后弹出前面提到的收藏清单。到现在为止一切都很好!我甚至可以在数组中循环以仅获取集合的名称:

    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
    

    尽管通过循环获得该系列似乎效果很好:

    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 结构是我循环的问题,但我不确定到底发生了什么。。。 这是每个集合的预期输出示例:

    { _id: 5a13de85a55e615235f71528, b: 2 }
    

    任何帮助都将不胜感激!提前感谢!

    2 回复  |  直到 8 年前
        1
  •  2
  •   s.d    8 年前

    虽然这不是最好的语法,除了记录输出之外也没用,但对我来说确实有用:

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

    那么,可能查询条件与任何内容都不匹配?

    此外,承诺更好:

    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);
    })
    
        2
  •  1
  •   Rohan Das    8 年前

    相反,您可以使用名为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();
    });
    
    推荐文章