2013-04-03 90 views
0

聚合框架的$max運算符如何評估複合鍵。例如:

{ 
    $project: { 
    user: 1, 
    record: { date: "$upload_date", comment: 1, some_integer: 1 } 
    } 
}, 
{ 
    $group: { 
    _id: "$user", 
    latest: { $max : "$record" } 
    } 
} 

是否會得到datecomment,或some_integer得到最大的?我只是假定它會得到最新的date。如果出錯,那麼通過date找到最大值的正確方法是什麼?

編輯

從我到目前爲止已經試過,最新的記錄是由第一個關鍵決定。這是正確的行爲?

編輯

給我的使用情況的想法,我有以下文件:

> db.logs.findOne() 
    { 
    'id': ObjectId("50ad8d451d41c8fc58000003") 
    'name': 'Sample Log 1', 
    'uploaded_at': ISODate("2013-03-14T01:00:00+01:00"), 
    'case_id': '50ad8d451d41c8fc58000099', 
    'result': 'passing' 
    'tag': ['TAG-XYZ'] 
    } 

而且我有以下聚合:

db.test_case_logs.aggregate(
    {$project: {tag:'$tag', case:'$case_id', 
    latest: {upload_date:1, date:'$upload_date', result:'$result', 
    passing : { $cond : [ { $eq : ["$result","passing"] }, 1, 0 ] }, 
    failing : { $cond : [ { $eq : ["$result","failing"] }, 1, 0 ] }} 
    }}, 
    {$unwind: '$tag'}, 
    {$group: {_id:{tag:'$tag',case:'$case'}, latest:{$max:'$latest'}}}, 
    {$group: {_id:'$_id.tag',total:{$sum:1}, passing:{$sum:{$latest.passing}}, 
    failing:{$sum:{$latest.failing}, date:{$max:{$latest.upload_date}}} 
    }, 
    {'$sort': {'date':-1}} 
) 

日誌可以有同名tagcase_id,並在分組兩次後,我需要的結果只是最新的日誌upload_date每個tag

編輯

我預期的結果是一樣的東西:

{ 
    '_id':'TAG-XYZ', 
    'total':'1' 
    'passing':'1' 
    'failing':'0' 
    } 

每個計數對應於最新的日誌給定的情況。

+0

你使用的是什麼版本的MongoDB? – Stennie

+0

我正在使用MongoDB 2.2 – MervS

+0

在更新的聚合操作中,您[展開](** tag **)字段的**標記**字段,但值標記不是一個數組,這會產生一個錯誤。你能否提供關於查詢和預期結果的更多信息? (例如$ sum操作) –

回答

0

$max documentation,該運營商

返回此組中的所有文檔領域的所有值中的最高值。

聚集操作是這樣的:

您可以通過{ 「$ record.date」 $最大}:指定日期的操作最大

db.collection.aggregate ([ 
    { $project: { 
     user: 1, 
     record: { date: "$upload_date", comment: 1, some_integer: 1 } 
    }}, 
    { $group: { 
     _id: "$user", 
     latest: { $max : "$record.date" } 
    }} 
]) 
+0

是的,我想,它會得到最新的'日期'。但是如果我想保留「record」字段的內容呢?也就是說,我想要得到'date','comment'和'some_integer'與最大'date'的最新組合? – MervS

+0

@ nyde1319:如果您剛剛在基於日期值(或其他條件)的最新記錄之後,則不需要使用聚合框架。只要做一個'db.collection.find()。sort({'date': - 1})。limit(1)'。 – Stennie

+0

@Stennie:請參閱最新的問題以獲得解釋。 – MervS

0

對於你的情況,你可以使用$sort運算符按$ uploaded_at字段對所有日誌進行排序,然後按標記和case_id對排序結果進行分組,然後使用$first運算符獲取每個組的第一個項目。

db.logs.aggregate([ 

    // Rename the fields and process the result field 
    { $project : { 
      tag : 1, 
      case : "$case_id", 
      date : "$uploaded_at", 
      result : { 
       passing : { $cond : [ { $eq : ["$result","passing"] }, 1, 0 ] }, 
       failing : { $cond : [ { $eq : ["$result","failing"] }, 1, 0 ] }} 
    }}, 

    // Create a stream of documents from the tag array 
    { $unwind : "$tag" }, 

    // Sort by uploaded date descending 
    { $sort : { date : -1 }}, 

    // Group the documents by tag and case_id, and use $first operation to get the latest log for each group 
    { $group : { 
      _id : { tag : "$tag", case : "$case" }, 
      latest : { $first : "$result" }, 
    }}, 

    // Group the document by tag, and caculate the total/pass/fail results 
    { $group : { 
      _id : "$_id.tag", 
      total : { $sum : 1 }, 
      passing : { $sum : "$latest.passing" }, 
      failing : { $sum : "$latest.failing" } 
    }} 
]) 
+0

我想這會起作用,但我想知道我使用'$ max'操作符有什麼意義。結果會不可預測嗎? – MervS

+0

@ nyde1319 $ sort(在特定字段中降序)和$ first操作可以幫助我們獲得此特定字段的最大結果。 –

+0

在我的案例中有大量文檔,我使用'$ sort'管道看到的問題是它可能會消耗大量的內存[http://docs.mongodb.org/manual /核心/匯聚/#存儲器換累積運算符)。 – MervS