mongodb aggregation framework - Fetch first document's field of the nested array

mongodb

Solution

The easiest way to achieve your result is using a normal find query and the `$slice` operator:

db.collection.find( {_id: "User1"}, {"likes.sublikes": {$slice: 1}} )

The aggregation framework (as at MongoDB 2.4.1) does not support `$slice` or array indexes (vote/watch feature requests: SERVER-6074 and SERVER-4589).

You could do this in aggregation framework using `$unwind`, `$group` and the `$first` operator, eg:

db.collection.aggregate([
    { $match: {
         _id : "User1"
    }},
    { $unwind: "$likes.sublikes" },
    { $group: {
        _id: "$_id",
        like: { $first: "$likes.sublikes" }
    }},
    { $project: {
        _id: 0,
        "UserID": "$_id",
        "WebsiteName": "$like.WebsiteName"
    }}
])

The normal `$slice` should be the most performant option.

Problem

Consider the following is my document stored in collection `Users` ``` { _id : "User1", joined : ISODate("2011-03-02"), likes : { sublikes: [ {WebsiteID:'001': WebsiteName: 'ABCD'}, {WebsiteID:'002': WebsiteName: '2BC2'}, {WebsiteID:'003': WebsiteName: '3BC3'}, //........... //........... {WebsiteID:'999999': WebsiteName: 'SOME_NAME'} ] } } ``` Now using mongodb aggregation framework I need to fetch that ``` collection.aggregate([ { $project: { _id: 1, "UserID": "$_id", "WebsiteName": "$likes.sublikes[0]['WebsiteName']" } }, { $match: { _id: 'User1'} } ], function (err, doc) { ///Not able to get the WebsiteName: 'ABCD' }); ``` If I use `$unwind` the document becomes bulk (specifically in the above case), So I don't want to unwind it for getting only first item in an array (irrespective of others) Can anyone give me hints on how to access is and rename that field? Update 1: Even I tried to project with `"WebsiteName": "$likes.sublikes.0.WebsiteName"`. Didn't work :-( Update 2: Open issue - https://jira.mongodb.org/browse/SERVER-4589 As of now `$at` does not work. Throws an error: ``` { [MongoError: exception: invalid operator '$at'] name: 'MongoError', errmsg: 'exception: invalid operator \'$at\'', code: 15999, ok: 0 } ``` Till then using `$unwind` ``` // Array Remove - By John Resig (MIT Licensed) Array.prototype.remove = function(from, to) { var rest = this.slice((to || from) + 1 || this.length); this.length = from < 0 ? this.length + from : from; return this.push.apply(this, rest); }; ```

Original source