Reputation: 34939
I have two separate collections, suppose news
and pictures
. Both collections have a creationDate
field that holds a datetime
of records creation time.
What I want is to select last 10 records from both collections, join all records (now the list has 20 records) and then sort all records by creationDate
field. How it's possible in Mongoose?
Upvotes: 0
Views: 4887
Reputation: 151122
Well what you are asking for is essentially a client side operation, and you really only want at most 20 records to sort so that should not be a problem.
The async.concat method should help a little here:
async.concat([News,Picture],function(model,callback) {
// Get the last 10 results from each collection
var query = model.find({}).sort({ "creationDate": -1 }).limit(10);
query.exec(function(err,docs) {
if (err) throw err;
callback(err,docs);
});
},
function(err,result) {
if (err) throw err;
// results are merged, now sort by date
result = result.sort(function(a,b) {
return (a.creationDate < b.creationDate)
? 1 : (a.creationDate > b.creationDate) ? -1 : 0;
});
console.log(result);
});
So really you are just "merging" two arrays, but coding it that way simplifies things.
An end to end listing to clarify the usage here. This sets up some documents for each model before running the code as shown above:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/series');
var newsSchema = new Schema({
type: { type: String, default: "News" },
index: Number,
creationDate: { type: Date, default: Date.now }
});
var pictureSchema = new Schema({
type: { type: String, default: "Picture" },
index: Number,
creationDate: { type: Date, default: Date.now }
});
var News = mongoose.model( "News", newsSchema );
var Picture = mongoose.model( "Picture", pictureSchema );
async.series(
[
// Clean existing
function(callback) {
async.each([News,Picture],function(model,callback) {
model.remove(function(err) {
if (err) throw err;
callback();
});
},function(err) {
callback();
});
},
// Insert 20 of each
function(callback) {
console.log("inserting");
var count = 0;
async.whilst(
function() { return count < 20 },
function(callback) {
count++;
async.eachSeries([News,Picture],function(model,callback) {
var doc = new model({ index: count });
setTimeout(function() {
doc.save(function(err) {
if (err) throw err;
callback();
});
}, 20);
},function(err) {
callback();
});
},
function(err) {
callback();
}
);
}
],
function(err) {
console.log("listing");
// Get the last 10 of each
async.concat([News,Picture],function(model,callback) {
var query = model.find({}).sort({ "creationDate": -1 }).limit(10);
query.exec(function(err,docs) {
if (err) throw err;
callback(err,docs);
});
},
function(err,result) {
if (err) throw err;
// result is merged via "concat" now sort it.
result = result.sort(function(a,b) {
return (a.creationDate < b.creationDate)
? 1 : (a.creationDate > b.creationDate)
? -1 : 0;
});
console.log(result);
mongoose.disconnect();
});
}
);
Output is somewhere along these lines:
[ { _id: 53c79f4b7daf2d676ff0f185,
index: 20,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'Picture' },
{ _id: 53c79f4b7daf2d676ff0f184,
index: 20,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'News' },
{ _id: 53c79f4b7daf2d676ff0f183,
index: 19,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'Picture' },
{ _id: 53c79f4b7daf2d676ff0f182,
index: 19,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'News' },
{ _id: 53c79f4b7daf2d676ff0f181,
index: 18,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'Picture' },
{ _id: 53c79f4b7daf2d676ff0f180,
index: 18,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'News' },
{ _id: 53c79f4b7daf2d676ff0f17f,
index: 17,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'Picture' },
{ _id: 53c79f4b7daf2d676ff0f17e,
index: 17,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'News' },
{ _id: 53c79f4b7daf2d676ff0f17d,
index: 16,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'Picture' },
{ _id: 53c79f4b7daf2d676ff0f17c,
index: 16,
__v: 0,
creationDate: Thu Jul 17 2014 20:02:51 GMT+1000 (EST),
type: 'News' } ]
Upvotes: 1