[已解决]Nodejs中mongoose的find(query, fields, options, callback){}问题

[已解决]Nodejs中mongoose的find(query, fields, options, callback){}问题

我在Post.find(query, fields, options, function(err, results){}中,把fields设置为[’_id’]就会报500 TypeError: Invalid select() argument. Must be a string or object.

 exports.index = function(req, res, next){
var current_page = parseInt(req.query.page, 10) || 1;
var limit = 15;
var render = function(posts, pages){
	res.render('index', {
		posts: posts,
	});
}
var proxy = new EventProxy();
proxy.assign('posts', render);
var where = {};
var options = {skip: 0, limit: limit, sort: {create_at: 1}};
postCtrl.find_posts_by_query(where, options, function(err, posts){
	if(err){
		return next(err);
	}
	proxy.trigger('posts', posts);
});

}

exports.find_posts_by_query = function(where, options, callback){
Post.find(where, ['_id'], options, function(err, results){
	if(err){
		return callback(err, null);
	}
	if(results.length == 0){
		return callback(err, []);
	}
	var posts_id = [];
	for(var i = 0; i < results.length; i++){
		posts_id.push(results[i]._id);
	}
	var proxy = new EventProxy();
	var done = function(){
		return callback(null, posts);
	}

	var posts = [];
	proxy.after('posts.ready', posts_id.length, done);
	var where = {};
	for(var i = 0; i < posts_id.length; i++){
		(function(i){
			where = {_id: posts_id[i]};
			find_post_by_query_once(where, function(err,post, author){
				if(err){
					callback(err);
				}
				post.author = author;
				proxy.trigger('posts.ready');
			});
		})(i);
	}
});

}

原因是fields不是数组而是字符串,多字段用空格分隔


3 回复

好的,我明白你的问题了。在Mongoose的find()方法中,第二个参数fields应该是一个对象,而不是一个数组。你当前将fields设置为['_id'],这会导致错误。正确的做法是使用对象来指定需要选择或排除的字段。

下面是修改后的代码示例:

修改后的代码

exports.index = function(req, res, next){
    var current_page = parseInt(req.query.page, 10) || 1;
    var limit = 15;
    var render = function(posts, pages){
        res.render('index', {
            posts: posts,
        });
    }
    var proxy = new EventProxy();
    proxy.assign('posts', render);

    var where = {};
    var options = {skip: 0, limit: limit, sort: {create_at: 1}};

    postCtrl.find_posts_by_query(where, options, function(err, posts){
        if(err){
            return next(err);
        }
        proxy.trigger('posts', posts);
    });
}

exports.find_posts_by_query = function(where, options, callback){
    Post.find(where, {'_id': 1}, options, function(err, results){
        if(err){
            return callback(err, null);
        }
        if(results.length == 0){
            return callback(err, []);
        }

        var posts_id = [];
        for(var i = 0; i < results.length; i++){
            posts_id.push(results[i]._id);
        }

        var proxy = new EventProxy();
        var done = function(){
            return callback(null, posts);
        }

        var posts = [];
        proxy.after('posts.ready', posts_id.length, done);

        for(var i = 0; i < posts_id.length; i++){
            (function(i){
                var where = {_id: posts_id[i]};
                find_post_by_query_once(where, function(err, post, author){
                    if(err){
                        callback(err);
                    }
                    post.author = author;
                    proxy.trigger('posts.ready');
                });
            })(i);
        }
    });
}

解释

  • fields 参数:现在我们将其设置为 {'_id': 1}。这里的 1 表示选择 _id 字段,而 0 表示排除某个字段。

    Post.find(where, {'_id': 1}, options, function(err, results){ ... })
    
  • 其他部分保持不变:这部分代码主要是用于查询和处理结果,并且通过事件代理机制确保所有查询完成后才调用回调函数。

通过这样的修改,你可以正确地选择 _id 字段,而不会引发 TypeError 错误。希望这对你有所帮助!


嗯,字段前面加-表示非

根据你的描述,问题在于fields参数应该是一个字符串而不是数组。Mongoose 的 find 方法中的 fields 参数需要一个字符串来指定选择的字段。如果需要选择多个字段,字段之间需要用空格分隔。

下面是修正后的代码示例:

修改后的 index 函数

exports.index = function(req, res, next) {
    var current_page = parseInt(req.query.page, 10) || 1;
    var limit = 15;

    var render = function(posts, pages) {
        res.render('index', {
            posts: posts,
        });
    }

    var proxy = new EventProxy();
    proxy.assign('posts', render);

    var where = {};
    var options = { skip: 0, limit: limit, sort: { create_at: 1 } };

    postCtrl.find_posts_by_query(where, options, function(err, posts) {
        if (err) {
            return next(err);
        }
        proxy.trigger('posts', posts);
    });
}

修改后的 find_posts_by_query 函数

exports.find_posts_by_query = function(where, options, callback) {
    Post.find(where, '_id', options, function(err, results) {
        if (err) {
            return callback(err, null);
        }
        if (results.length == 0) {
            return callback(err, []);
        }

        var posts = results.map(post => ({
            _id: post._id
        }));

        callback(null, posts);
    });
}

关键修改点

  1. fields 参数:将 ['_id'] 改为 '_id'
  2. 处理结果:简化了对结果的处理,直接返回 _id 字段。

通过这些修改,你可以避免 TypeError 并正确地从数据库中获取 _id 字段。

回到顶部