This is my Schema:
var userschema = new mongoose.Schema({
user: String,
follow: [String],
imagen: [{
title: String,
date: { type: Date, default: Date.now }
}]
});
And this is the code:
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
});
});
});
The follow contains users's _id.
The code works, except when I include the $match. I use the $matchto filter the result, only getting the images of the user that I'm following, but the console.log show me that the result of the aggregate search is undefined, but when I don't write the $match query, I get the images, but I obtain all the images, not only the images of the user that I'm following.
Is there any solution for this...?
Thank's advance!
EDIT:
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
});
}
});
});
EDIT:
[ { __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 middleware also supports pre('aggregate') and post('aggregate') hooks. You can use aggregation middleware to transform the aggregation pipeline.
The $match stage of the pipeline can be used to filter documents so that only ones meeting certain criteria move on to the next stage. In this article, we'll discuss the $match stage in more detail and provide examples that illustrate how to perform match aggregation in MongoDB.
Connecting to MongoDBMongoose requires a connection to a MongoDB database. You can require() and connect to a locally hosted database with mongoose. connect() as shown below (for the tutorial we'll instead connect to an internet-hosted database). You can get the default Connection object with mongoose.
To use $text in the $match stage, the $match stage has to be the first stage of the pipeline.
Mongoose doesn't do any schema-based casting of the arguments of aggregate, so you need to convert your user.follow array of string ids into an array of ObjectIds in the $match:
{$match: { _id: {
$in: user.follow.map(function(id){ return new mongoose.Types.ObjectId(id); })
}}},
NOTE: Do not use mongoose.Schema.Types.ObjectId for casting. It will not work.
You should also move this $match to the beginning of the pipeline for efficiency.
UPDATE
Your other problem is you need to use a $project operator instead of just including a plain {imagen: true} object in the pipeline. Putting it all together and reordering for a more efficient pipeline, this worked for me with your data:
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){ ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With