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 日付で並べ替えたいと考えています。次のクエリで Aggregation Framework を使用してこれを実行しようとしました。

  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

最初に一致を行うと、インデックスを使用できるようになります (「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 に答える
0

この問題は、グループ関数を使用するとより簡単に解決できます。

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 に答える