如何在Mongoose中循环收集

时间:2014-06-28 17:46:04

标签: node.js mongoose

我正在尝试遍历Mongoose中基础连接中的所有集合:

var chai = require('chai'),
    expect = chai.expect,
    mongoose = require('mongoose'),
    db = mongoose.connection;

describe('Blog Tests', function () {

    before(function () {
        console.log('before called');
        db.on('error', console.error);

        mongoose.connect('mongodb://localhost/mydb', function(err){
            if(err)console.err(err);

            // never loops through collections at this point!
            for (var i in mongoose.connection.collections) {
                console.log(mongoose.connection.collections[i]);
                // will drop collection here
            }
        });
    });

    after(function(){
        console.log('after called');
        if(db.db._state === 'connected'){
            console.log('closing db');
            db.close();
        }
    });

    it('Can add a blog post', function (done) {
        db.on('open', function(){
            var blogPostSchema = new mongoose.Schema({
                    id: mongoose.Schema.ObjectId,
                    title: {type: String, required: true},
                    content: {type: String},
                    tags: []
                }),
                BlogPost = mongoose.model('BlogPost', blogPostSchema),
                blogPost = new BlogPost({
                    title: 'Hello World',
                    content: 'Lorem baby',
                    tags: [{"tag": "tests"},{"tag": "mocha"}, {"tag": "chai"}]
                });

            blogPost.save(function(err, saved){
                if (err) console.error(err);
                expect(saved.title).is.equal('Hello World');
                done();
            });
        });
    });
});

然而它永远不会返回集合 - 并且它们存在defs,它只返回一个空对象;不是一个空数组。

有人能发现这个愚蠢的错误吗?

根据Gergo建议更新,但仍未显示收藏品:

var chai = require('chai'),
    expect = chai.expect,
    mongoose = require('mongoose'),
    db = mongoose.connection;

describe('Blog Tests', function () {

    before(function (done) {
        console.log('before called');
        db.on('error', console.error);

        mongoose.connect('mongodb://localhost/mydb', function(err){
            if(err) return console.err(err);

            // never loops through collections at this point!
            for (var i in mongoose.connection.collections) {
                console.log(mongoose.connection.collections[i]);
                // will drop collection here
            }
            done();
        });
    });

    after(function(done){
        console.log('after called');
        if(db.db._state === 'connected'){
            console.log('closing db');
            db.close();
            done();
        }
    });

    it('Can add a blog post', function (done) {
            var blogPostSchema = new mongoose.Schema({
                    id: mongoose.Schema.ObjectId,
                    title: {type: String, required: true},
                    content: {type: String},
                    tags: []
                }),
                BlogPost = mongoose.model('BlogPost', blogPostSchema),
                blogPost = new BlogPost({
                    title: 'Hello World',
                    content: 'Lorem baby',
                    tags: [{"tag": "tests"},{"tag": "mocha"}, {"tag": "chai"}]
                });

            blogPost.save(function(err, saved){
                if (err) console.error(err);
                expect(saved.title).is.equal('Hello World');
                done();
            });
    });
});

1 个答案:

答案 0 :(得分:0)

mongoose.connect是异步的,前一个块的执行在调用mongoose.connect的回调之前完成。使用done参数并在回调中调用它:

before(function(done) {
    console.log('before called');
    db.on('error', console.error);

    mongoose.connect('mongodb://localhost/mydb', function(err){
        if(err) return console.err(err);

        // never loops through collections at this point!
        for (var i in mongoose.connection.collections) {
            console.log(mongoose.connection.collections[i]);
            // will drop collection here
        }
        done();
    });
});

此外,将if(err) console.err(err);更改为if(err) return console.err(err);,因为即使出现错误,您当前的代码也会继续执行。使用if(err) return done(err);

会更好

编辑:我测试了代码,但确实无效。但是发现问题不在于异步执行,而在于mongoose.connection.collections。连接打开时,mongoose.connection.collections的值为空对象{}。这就是你的for循环不能按预期工作的原因。但是以下工作:

mongoose.connection.db.collectionNames(function(err, names) {
  console.log(names);
});

所以你可以像这样重写你的代码:

before(function(done) {
    console.log('before called');
    db.on('error', console.error);

    mongoose.connect('mongodb://localhost/mydb', function(err) {
        if (err) return done(err);

        mongoose.connection.db.collectionNames(function(err, names) {
            console.log(names);
        });

        done();
    });
});