2012-10-11 89 views
0

所有对象我有对象的MongoDB中的集合,它看起来像这样集团使用聚合框架

{ "event_type": "event1", "created_at": some_date, ...more_fields... }, 
    { "event_type": "event2", "created_at": some_date, ...other_fields... }, 
    { "event_type": "event1", "created_at": some_date, ...more_fields... } 

现在我想有一些领域分组的所有领域上面的数据(这可能不会出现在所有对象)并按最高的created_at日期排序。我试图做到这一点使用聚合框架用下面的查询:

collection.aggregate([ 
    { "$group" => { 
     :_id  => "$somefield", 
     :last_time => { "$max" => "$created_at" }, 
     :events => { "$push" => { ... } } 
     } 
    }, 
    { "$match" => { "_id" => { "$ne" => nil } } }, 
    { "$sort" => { "last_time" => -1 } } 
    ]) 

我面对如果我把一些具体领域是关系到线

:events => { "$push" => { ... } } 

的问题,那么它的工作原理,但我不知道集合包含哪些确切的字段。反倒是我想整个对象返回是这样的:

{ 
     "event_type": "event1", "last_time": some_date, "events": [ 
      { "event_type": "event1", "created_at": some_date, ...more_fields... }, 
      { "event_type": "event1", "created_at": some_date, ...more_fields... }, 
      ... 
     ] 
    } 

回答

0

,如果你先做了比赛,你就可以使用索引(如果在“somefield”的存在)

可能呢是否需要投影你想为每个聚合值创建一个数组的子文档?我没有测试过这个,但可能会希望将你指向正确的方向?

有点像?

db.collection.aggregate( 
{ $match : { "some_field" : { $ne:null} } }, 
{ $project : 
    { 
     event_type :"event_type", 
     created_at: "created_at", 
     event: 
     { 
      another_att: "attrib1", 
      another_att2: "attrib2" 
     } 
    }, 
{ $group : 
    { 
     _id: "$event_type", 
     lasttime : { $max: "$created_at"}, 
     theevents: { $addToSet : "$event" } 
    } 
}) 
1

假设你要推的所有字段在你的对象,不知道到底是什么这些字段,不能你只是包装他们在已知领域的父母和推动呢?

{ events: { 
    "event_type": "event1", "created_at": some_date, ...more_fields... 
    } 
}, 

然后你只需要推“事件”。

+0

这会工作,但我宁愿不必改变数据的形状。我最终通过一个简单的组呼和在客户端进行排序完成。 – derfred

0

这个问题解决更容易使用组函数:

options = { 
    key:  "field_to_group_by", 
    cond:  { ..some filter criteria.. }, 
    initial: { :events => [] }, 
    reduce: "function(obj, agg) { agg.events.push(obj); }" 
} 
collection.group(options) 

在我想要的顺序这不返回的项目,但排序可以在客户端上完成。

+0

难道你不能只添加group()上的.Sort()? – cirrus