如何在mongodb中分组以生成对象列表?

时间:2013-01-26 10:58:33

标签: javascript node.js mongodb

我有这样的数据,

{
    meta: {
        artist: "artist",
        album: "album",
        year: 2008
    }
}

我希望对艺术家执行SQL组的等效操作,以使用mongodb聚合生成{ album: album, year: year }的对象列表。

我有这个问题几乎是我想要的,但我不认为这是正确的做法。

db.pending.aggregate( [ 
    { $project: 
      { 'meta.artist': 1, 'meta.album': 1, 'meta.year':1 } 
    }, 
    { $group: 
      {
       '_id': 
         { artist: '$meta.artist', album: '$meta.album', 
             year: { $year: '$meta.year'}  
         } 
      }
    }
] )

2 个答案:

答案 0 :(得分:1)

我认为您可以通过以下聚合框架执行以下操作:

db.pending.aggregate(
  {$group: {_id: '$artist', albums: {$push: {album: '$album', year: '$year'}}}}, 
  {$sort: {_id: 1}}
);

或者你可以通过map reduce函数来实现:

var mapFunction = function() {
                       emit(this.meta.artist, {album: this.meta.album, year: this.meta.year});
                   };

var reduceFunction = function(artistId, albumValues) {
                     var reducedObject = {
                                artisId: artistId,
                                albums: []};

                    albumValues.forEach( function(albumValue) {
                                   reducedObject.albums.push(
                                       {album: albumValue.album,
                                       year: albumValue.year}
                                        );
                                   });
                        return reducedObject;
};

db.pending.mapReduce(
                     mapFunction,
                     reduceFunction,
                     { out: { inline: 1 } }
                   )

我认为您不能通过查询按SQL组执行所需的操作。这将返回与此{_id: "artisName", values[{album: 'album1', year: 'year1'}, {album: 'album2', year: 'year2'}]}

类似的结果

答案 1 :(得分:1)

我认为您需要$addToSet运算符:

db.test.aggregate(
  { $project:
    { 'meta.artist': 1
    , 'meta.album': 1
    , 'meta.year': 1 }
  }
  , { $group:
      { _id: '$meta.artist'
      , albums: {
        $addToSet: {
          album: '$meta.album'
        , year: '$meta.year' }
      }
    }
  }
)