0

次のような「イベント」というコレクションがあります。

{
        "_id" : ObjectId("4fd89f8d3cbec825d7000001"),
        "type" : "lms_course_view",
        "datetime" : ISODate("2011-12-23T12:55:00Z"),
        "user" : [
                {
                        "_id" : ObjectId("4fd89f8d3cbec825d7000000")
                }
        ]
}

そして、次のように「ユーザー」と呼ばれる別のもの:

{
        "_id" : ObjectId("4fd89f8d3cbec825d7000000"),
        "name" : "02ad1046f",

         (...)
}

各ユーザーが各イベント タイプを生成した回数をカウントしようとしています。map-reduce を試していますが、ユーザーの名前 (別のコレクションに保存されている) を発行しながらイベントを反復処理する map 関数を作成する方法がわかりません。

どんな手掛かり?map-reduce で可能ですか?

4

2 に答える 2

1

ユーザーの名前はコレクションとは別に保存されるため、eventsとにかく 2 つのパスを作成する必要があります。Aggregation Frameworkuser["_id"]を使用してからuser["name"]、2 番目のパスで を に変換することをお勧めします。集約フレームワークのコードは次のようになります。

db.events.aggregate(
    { $unwind: "$user" }, // breaks apart user array into separate documents
    { $group: {
        _id: { user: "$user._id", type: "$type" }
        count: { $sum: 1 }
    } }
);
于 2012-11-22T18:47:58.410 に答える
0

あなたのスキーマは、指定されたユースケースに対して不十分に構築されているようです。

再考し、ユーザー名をイベント コレクションに非正規化することをお勧めします。

複数のユーザーが各イベントを生成できるため、ユーザー フィールドは配列であると想定します。その場合でも配列ですが、各要素には 2 つのフィールドがあります。現在のように _id と、ユーザーの名前を表す名前です。ユーザー名は (あったとしても) あまり頻繁に変更されないため、これは比較的 "安全" です。

そのスキーマを取得したら、MapReduce を使用するか ({user name, event type} をキーとして発行する)、または @slee が回答で説明する方法で集計フレームワーク (バージョン 2.1 以降) を使用するかを選択できます。

于 2012-11-22T20:35:41.360 に答える