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... },
            ...
        ]
    }
4

3 回答 3

1

假设您想推送对象中的所有字段,但不知道这些字段到底是什么,您不能将它们包装在已知的字段父项中并推送吗?

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

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

于 2012-10-11T14:50:56.363 回答
0

使用 group 函数可以更轻松地解决此问题:

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

这不会按我想要的顺序返回项目,但可以在客户端上进行排序。

于 2012-10-11T17:14:18.790 回答
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" }
    }
 })
于 2012-10-11T14:49:39.830 回答