2013-04-03 3 views
0

집계 프레임 워크의 $max 연산자가 복합 키를 평가하는 방법은 무엇입니까? 예를 들어 :

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

그것은 date, comment, 또는 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을 두 번 그룹화 한 후 결과가 최신 로그 만 필요합니다. 각 tag에 대해 upload_date 각 계수는 주어진 케이스의 최신 로그에 해당

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

:

편집

내 예상 결과는 무엇인가 같다. $max documentation

+0

어떤 MongoDB 버전을 사용하고 있습니까? – Stennie

+0

MongoDB 2.2를 사용하고 있습니다. – MervS

+0

업데이트 된 집계 작업에서 ** tag ** 필드는 [unwind] (http://docs.mongodb.org/manual/reference/aggregation/unwind/)이지만 값은 태그가 배열이 아니면 오류가 발생합니다. 쿼리 및 예상 결과에 대한 자세한 정보를 제공 할 수 있습니까? (예 : $ sum 연산) –

답변

0

이 오퍼레이터

이 그룹에 의해 선택된 모든 문서에서 필드의 모든 값 중에서 가장 큰 값을 반환.

집계 작업은 다음과 같이이다 :

당신은 { "$의 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 필드로 모든 로그를 정렬하고 정렬 된 결과를 tag 및 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