Question

I have such Collection structure

{
    "_id" : "12ds5dsfSSFS2sfds",
    "name": "Peter Jackson",
    "films" : [
        {
            "name" : "King Kong",
            "date" : "2005"
        },
        {
            "name" : "The Hobbit: An Unexpected Journey",
            "date" : "2012"
        }
    ]
},
{
    "_id" : "HHdfdsBfSSFS2sfds",
    "name": "Martin Scorsese",
    "films" : [
        {
            "name" : "Goodfellas",
            "date" : "1990"
        },
        {
            "name" : "The Wolf of Wall Street",
            "date" : "2013"
        }
    ]
}

What I need is to have sorted list like this:

http://jsfiddle.net/K7VGy/embedded/result/

Sorted list as a result

So, the question is - is it possible to merge all fields from films arrays, then sort them, based on date and then pass to template?

Maybe I have chosen the wrong collection structure, and it could be improved somehow?

Any help will be appreciated!

Was it helpful?

Solution

For mine I would do this server side with the use of the aggregate method, and doing this server side you need to do some digging to get at the aggregate method:

var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;

db.collection("server_collection_name").aggregate([
    { "$unwind": "$films" },
    { "$sort": { "films.date": -1 } },
],
function(err,result) {

    // do work in here   
});

Which will essentially return data already formatted and ordered like so:

{
    "_id" : "HHdfdsBfSSFS2sfds",
    "name" : "Martin Scorsese",
    "films" : {
            "name" : "The Wolf of Wall Street",
            "date" : "2013"
    }
},
{
    "_id" : "12ds5dsfSSFS2sfds",
    "name" : "Peter Jackson",
    "films" : {
            "name" : "The Hobbit: An Unexpected Journey",
            "date" : "2012"
    }
},
{
    "_id" : "12ds5dsfSSFS2sfds",
    "name" : "Peter Jackson",
    "films" : {
            "name" : "King Kong",
            "date" : "2005"
    }
},
{
    "_id" : "HHdfdsBfSSFS2sfds",
    "name" : "Martin Scorsese",
    "films" : {
            "name" : "Goodfellas",
            "date" : "1990"
    }
}

Then you can do really cool things with that on the server such as change the filtering, or the sort order and paginate results.

So I think this is the better way than manipulating a structure like above on the client, in which you could not possibly sort and then paginate.

That would be the better way and you can make use of Meteor's publish in order make this look more integral, or just use meteor methods. See this other answer and another external discussion for more information on aggregation with meteor.

Also see the aggregation framework operator reference for further information on how to customize.

OTHER TIPS

How about using underscore for merging:

var merged = _.extend({}, first_obj, second_obj);

For sorting we can also use underscore:

var sorted = _.sortBy(merged, function(item) {
    return new Date(item.films.date)*(-1); // to convert it to negative number
}

Then use newly created sorted variable in a template helper to output this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top