不能使用猫匹配mongoose和聚合框架

这是我的模式:

var userschema = new mongoose.Schema({ user: String, follow: [String], imagen: [{ title: String, date: { type: Date, default: Date.now } }] }); 

这是代码:

  usermodel.findOne({ user: req.session.user }, function (err, user){ usermodel.aggregate({$unwind: '$imagen'}, {$match: { _id: { $in: user.follow } }}, {imagen: true}, {$sort: {'imagen.date': 1}}, function (err, images){ console.log(images); res.render('home.ejs', { user: user, following: images }); }); }); 

follow包含用户的_id

代码的作品,除了当我包括$match 。 我使用$match来筛选结果,只得到我跟踪的用户的图像,但console.log显示aggregatesearch的结果是未定义的,但是当我不写$match查询,我得到的图像,但我获得所有的图像,不仅是我所遵循的用户的图像。

有没有解决这个…?

感谢您的提前!

编辑:

 var express = require('express'); var MongoStore = require('connect-mongo')(express); var fs = require('fs'); var mongoose = require('mongoose'); var app = express(); app.listen(9191); var sessionStore = new MongoStore({db: 'session'}); app.configure(function(){ app.use(express.bodyParser()); app.set('views',__dirname + '/views'); app.set('view engine', 'ejs'); app.use(express.static(__dirname + '/public')); app.use(express.cookieParser()); app.use(express.session({ store: sessionStore, secret: 'secret' })); app.use(app.router); }); var db = mongoose.createConnection('localhost', 'test'); var userschema = new mongoose.Schema({ user: String, follow: [String], imagen: [{ title: String, date: { type: Date, default: Date.now } }] }); var usermodel = db.model('usermodel', userschema); var ObjectId = require('mongoose').Types.ObjectId; app.get('/', middleware.noses, function (req, res){ res.render('home0.ejs'); }); app.get('/home', middleware.yeses, function (req, res){ usermodel.findOne({ user: req.session.user }, function (err, user){ if (user.follow.length != 0){ usermodel.find({ _id: {$in: user.follow } }, { user: true }, function (err, users){ var usernames = users.map(function(u){ return u.user }); usermodel.aggregate({$match: { _id: { $in: user.follow.map( function(id){ return new ObjectId(id); })}}}, {$unwind: '$imagen'}, {imagen: true}, {$sort: {'imagen.date': 1}}, function (err, images){ console.log(images); res.render('home.ejs', { user: user, following: images }); }); }); } else { res.render('home.ejs', { user: user, following: undefined }); } }); }); 

编辑:

 [ { __v: 4, _id: 50fd9c7b8e6a9d087d000006, follow: ['50fd9cbd1322de627d000006', '50fd9d3ce20da1dd7d000006'], imagen: [{ title: 'foo', _id: 50fd9ca2bc9f163e7d000006, date: Mon Jan 21 2013 20:53:06 GMT+0100 (CET) }, { title: 'foot', _id: 50fda83a3214babc88000005, date: Mon Jan 21 2013 21:42:34 GMT+0100 (CET) }], user: 'Mrmangado' } 

Mongoose不会对aggregate参数进行基于模式的转换,因此您需要将您的user.followstring数组转换为$match的ObjectId数组:

 {$match: { _id: { $in: user.follow.map(function(id){ return new mongoose.Types.ObjectId(id); }) }}}, 

注意:不要使用mongoose.Schema.Types.ObjectId进行强制转换。 不起作用。

您也应该将这个$match移到stream水线的起点以提高效率。

UPDATE

你的另一个问题是你需要使用$project运算符,而不是在pipe道中包含一个普通的{imagen: true}对象。 把它放在一起,并重新sorting,以更有效的pipe道,这与我的数据:

 usermodel.aggregate( {$match: { _id: { $in: user.follow.map(function(id){ return new mongoose.Types.ObjectId(id); }) }}}, {$project: {imagen: true}}, {$unwind: '$imagen'}, {$sort: {'imagen.date': 1}}, function (err, images){ ... 

对于任何人在这个问题上磕磕碰碰,希望有一个更“通用”的解决scheme,需要手动地图或手动进行转换/转换,这里有一个解决schememay为你工作:

要求 :$匹配的查询对象必须符合您创build的某个模式。

一般解决scheme

 Model.aggregate([ { $match: Model.where(yourQueryObject).cast(QueryModel); } ]); 

这里的catch是Mongoose Query API的Query#cast转换,它可以帮助您将普通对象转换为模式定义的任何对象。 这有助于标准化ObjectID,string和数字。

这个问题的可能解决scheme

只考虑$匹配阶段:

 {$match: usermodel.where({_id: { $in: user.follow }}).cast(usermodel) }}