这是我的架构:
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告诉我aggregate
搜索的结果是未定义的,但是当我不写$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' }
答案 0 :(得分:19)
Mongoose不会对aggregate
的参数进行任何基于模式的转换,因此您需要将user.follow
字符串数组转换为$match
中的ObjectIds数组:
{$match: { _id: {
$in: user.follow.map(function(id){ return new mongoose.Types.ObjectId(id); })
}}},
注意:请勿使用mongoose.Schema.Types.ObjectId
进行投射。 无效。
为了提高效率,您还应将此$match
移至管道的开头。
<强>更新强>
您的另一个问题是您需要使用$project
运算符,而不是仅在管道中包含普通的{imagen: true}
对象。将所有内容放在一起并重新排序以获得更高效的管道,这对我的数据起了作用:
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){ ...
答案 1 :(得分:0)
任何偶然发现这个问题的人都希望获得更多的通用&#39;需要手动.map
或手动进行转换/转换的解决方案,这里是may
适合您的解决方案:
要求:$ match的查询对象必须符合您已创建的某个架构。
常规解决方案:
Model.aggregate([
{ $match: Model.where(yourQueryObject).cast(QueryModel); }
]);
这里的问题是Mongoose Query API的Query#cast
,它可以帮助您将普通对象转换为模式定义的任何内容。这有助于规范化ObjectID,字符串和数字。
此问题的可能解决方案:
仅考虑$ match阶段:
{$match: usermodel.where({_id: { $in: user.follow }}).cast(usermodel) }}