2

特定のユーザーと特定の場所の最新の開始および終了タイムスタンプを取得するのが好きです。コレクションはこんな感じ

{ "ActivityList" : [ 
{ "type" : "exit",
      "timestamp" : Date( 1348862537170 ),
      "user" : { "$ref" : "userProfile",
        "$id" : ObjectId( "4fdeaeeede26fd298262bb80" ) } }, 
    { "type" : "entry",
      "timestamp" : Date( 1348862546966 ),
      "user" : { "$ref" : "userProfile",
        "$id" : ObjectId( "4fdeaeeede26fd298262bb80" ) } }, 
       { "type" : "entry",
      "timestamp" : Date( 1348870744386 ),
      "user" : { "$ref" : "userProfile",
        "$id" : ObjectId( "4fdeaf6fde26fd298262bb81" ) } }, 
    { "type" : "exit",
      "timestamp" : Date( 1348878233785 ),
      "user" : { "$ref" : "userProfile",
        "$id" : ObjectId( "4fdeaf6fde26fd298262bb81" ) } } ],
  "Location" : { "$ref" : "loc",
    "$id" : ObjectId( "4fd410f0e7e994b59054b824" ) },
  "_id" : ObjectId( "4fe8f3c6e7e9ebe3697ee836" ) }

このようなことを試しましたが、機能しません

db.collection.group(
{
    keyf: function(doc) {
        return {
            location    :doc.Location._id,
             userid     : doc.ActivityList.user._id,           
             actiontype : doc. ActivityList.type
        };
    },
    reduce: function(obj,prev) {
        if (prev.maxdate < obj. ActivityList.timestamp) { 
            prev.maxdate = obj. ActivityList.timestamp; 
        } 
    },
    initial: {maxdate:0}
});

ご協力いただきありがとうございます。

4

1 に答える 1

2

$groupデータ構造と配列内の最大値の検索/フィルタリングでは単純には機能しません。配列を反復して最大値を見つける必要がありますが、これは、ドキュメントを取得してアプリケーション コードで反復することにより、より効率的に実行できます。

MongoDB 2.2 で可能なサーバー クエリ アプローチは、新しいAggregation Frameworkを使用することです。

db.activity.aggregate(

    // Find matching location documents first (can take advantage of index)
    { $match : {
        Location: {
            "$ref" : "loc", 
            "$id" : ObjectId("4fd410f0e7e994b59054b824")
        }
    }},

    // Unwind the ActivityList arrays as a document stream
    { $unwind : "$ActivityList" },

    // Filter activities to the user reference of interest
    { $match : {
       'ActivityList.user': {
            "$ref" : "userProfile",
            "$id" : ObjectId("4fdeaeeede26fd298262bb80")
        } 
    }},

    // Group the stream by activity types, and get the timestamp for the latest of each
    { $group : {
        _id : "$ActivityList.type",
        latest: { $max: '$ActivityList.timestamp' }
    }}
)

サンプル結果:

{
    "result" : [
        {
            "_id" : "entry",
            "latest" : ISODate("2012-09-28T20:02:26.966Z")
        },
        {
            "_id" : "exit",
            "latest" : ISODate("2012-09-28T20:02:17.170Z")
        }
    ],
    "ok" : 1
}
于 2012-10-08T14:14:52.450 に答える