我在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 :(得分:1)
假设您想要推送对象中的所有字段,而不确切知道这些字段是什么,那么您不能将它们包装在已知的字段父级中并推送它吗?
{ events: {
"event_type": "event1", "created_at": some_date, ...more_fields...
}
},
然后你只需要推送“事件”。
答案 1 :(得分:0)
如果您先进行匹配,则可以使用索引(如果“某些字段”存在)
你是否需要预测要为每个聚合值创建数组的子文档?我没有对此进行测试,但可能希望能指出正确的方向吗?
之类的东西?
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" }
}
})
答案 2 :(得分:0)
使用群组功能可以更轻松地解决此问题:
options = {
key: "field_to_group_by",
cond: { ..some filter criteria.. },
initial: { :events => [] },
reduce: "function(obj, agg) { agg.events.push(obj); }"
}
collection.group(options)
这不会按照我想要的顺序返回项目,但可以在客户端上进行排序。