i have article schema has subdocument comments contains comments got particular article.
what want select article id, populate author field , author field in comments. sort comments subdocument date.
the article schema:
var articleschema = new schema({ title: { type: string, default: '', trim: true }, body: { type: string, default: '', trim: true }, author: { type: schema.objectid, ref: 'user' }, comments: [{ body: { type: string, default: '' }, author: { type: schema.objectid, ref: 'user' }, created_at: { type : date, default : date.now, get: getcreatedatdate } }], tags: { type: [], get: gettags, set: settags }, image: { cdnuri: string, files: [] }, created_at: { type : date, default : date.now, get: getcreatedatdate } }); static method on article schema: (i love sort comments here, can that?)
load: function (id, cb) { this.findone({ _id: id }) .populate('author', 'email profile') .populate('comments.author') .exec(cb); }, i have sort elsewhere:
exports.load = function (req, res, next, id) { var user = require('../models/user'); article.load(id, function (err, article) { var sorted = article.toobject({ getters: true }); sorted.comments = _.sortby(sorted.comments, 'created_at').reverse(); req.article = sorted; next(); }); }; i call toobject convert document javascript object, can keep getters / virtuals, methods??
anyways, sorting logic on plain object , done.
i quite sure there lot better way of doing this, please let me know.
i have written out few things, on consideration "getting mongoose objects back" seems main consideration.
so there various things "could" do. since "populating references" object , wanting alter order of objects in array there 1 way fix once , all.
fix data in order create it
if want "comments" array sorted date "created_at" breaks down multiple possibilities:
it "should" have been added in "insertion" order, "latest" last note, can "modify" in recent ( past couple of years ) versions of mongodb
$positionmodifier$push:article.update( { "_id": articleid }, { "$push": { "comments": { "$each": [newcomment], "$position": 0 } } }, function(err,result) { // other work in here } );this "prepends" array element existing array @ "first" (0) index @ front.
failing using "positional" updates logical reasons or "want sure", there has been around "longer" time
$sortmodifier$push:article.update( { "_id": articleid }, { "$push": { "comments": { "$each": [newcomment], "$sort": { "$created_at": -1 } } } }, function(err,result) { // other work in here } );and "sort" on property of array elements documents contains specified value on each modification. can do:
article.update( { }, { "$push": { "comments": { "$each": [], "$sort": { "$created_at": -1 } } } }, { "multi": true }, function(err,result) { // other work in here } );and sort every "comments" array in entire collection specified field in 1 hit.
other solutions possible using either .aggregate() sort array and/or "re-casting" mongoose objects after have done operation or after doing own .sort() on plain object.
both of these involve creating separate model object , "schema" embedded items including "referenced" information. work upon lines, seems unnecessary overhead when sort data "most needed" means in first place.
the alternate make sure fields "virtuals" "serialize" object format .toobject() on call , live fact methods gone , work properties presented.
the last "sane" approach, if typically use "created_at" order, makes more sense "store" data way every operation when "retrieve" it, stays in order going use.
Comments
Post a Comment