2011-01-04 5 views
2

원래 모음 :mongodb mapreduce - 축소판에 배열 또는 객체를 만드시겠습니까?

{ 
"_id" : ObjectId('xxxxxxxxxxxxxxxx'), 
    "userId" : ObjectId('yyyyyyyyyyyyyyyy'), 
    "urlId" : ObjectId('zzzzzzzzzzzzzzzzzz') 
}, 
{ 
    "_id" : ObjectId('uuuuuuuuuuuuuuuuuu'), 
    "userId" : ObjectId('aaaaaaaaaaaaaaaa'), 
    "urlId" : ObjectId('zzzzzzzzzzzzzzzzzz') 
} 

는 방출 :

emit(this.urlId, {userId: this.userId, visitCount: this.visitCount}); 

가 감소 :

function(key, values) { 
    var visitCount = 0; 
    var userVC = new Array(); 
    values.forEach(function(doc) { 


NOT SURE WHAT TO PUT HERE TO ACHIEVE DESIRED OUTPUT COLLECTION 


    }); 
    return {urlId: key, userVC: userVC}; 
}; 

원하는 MR 출력 컬렉션 :

{ 
    "_id" : ObjectId('zzzzzzzzzzzzzzzzzzzz'), 
    "value" : { 
     "urlId" : ObjectId('zzzzzzzzzzzzzzzzzzzz'), 
     "userVC" : { 
       ObjectId('yyyyyyyyyyyyyyyy') : <total visit count for this userId on this urlId>, 
       ObjectId('aaaaaaaaaaaaaaaa') : <total visit count for this userId on this urlId> 
     } 
} 

답변

3

당신은 t을 원한다 o 각 사용자가 귀하의 사이트에서 각각의 개별 URL을 몇 번 방문했는지 알고 있습니까? 나는 이것을 다르게 풀고 싶을 것이라고 생각합니다.

는 URL/사용자가 방문의 수 방출 :

emit({ urlId: this.urlId, userId: this.userId }, { count: 1 }); 

하기로 카운트를 감소 : 다음

r = function(key , values){ 
    var total = 0; 
    for (var i=0; i<values.length; i++) 
     total += values[i].count; 
    return { count : total }; 
}; 

을 정말 정말 당신이 언급 원하는 출력을 원한다면, 당신은에 그렇게 할 수 마무리 단계. 하지만 N 사용자에게는 잘 맞지 않는다고 생각합니다. 여기

은 정확히 명시된 목표를 만족하지 않는 링크입니다,하지만, 이러한 MongoDB를 맵리 듀스 기능이 작동 방법을 이해하려고 할 때 나는 매우 유용하다고 : 사람들을위한

http://cookbook.mongodb.org/patterns/unique_items_map_reduce/

+0

두 번째 map-reduce 연산을 사용하여 사용자 AND 키의 키를 가진 콜렉션을 사용자의 키와 카운트 배열을 갖는 값으로 변환 할 수 있습니다. –

+0

당신이 count에 하나를 할당 했으므로'(var i = 0; i Danielo515

+0

그렇지 않습니다 @ Danielo515. 지도에서 카운트 1을 할당하지만, 감소는 임의의 순서로 여러 번 발생할 수 있으며, 하위 집합에서 이전에 값이 감소 된지도에서 방출 된 값을 혼합합니다. 즉, reduce 함수 내부에서 계수가 항상 하나가되는 것은 아닙니다. – Chris

0

다른이를 해결하기 위해 노력 줄이거 기능에 :

function reduce(key, values) { 
    const result = { 
    list: [], 
    ... 
    }; 

    // keep track of reduced records to avoid duplicate list entries 
    const processed = { 
    list: [], 
    ... 
    }; 

    values.forEach((value, index) => { 
    if (value.listItem && value.listItem.length > 0) { 

     // our value is an array as MongoDB needs to be strongly typed (same as reduced type) 
     if (processed.list.indexOf(value.listItem[0].key) === -1) { 
     result.list = result.list.concat(value.listItem); 
     } 

    } 
    ... 
    }); 

    return result; 
} 

는 당신이 지원하는 기능에 어떤 일이 일어나는지 알 필요가 있도록 기능이 MongoDB를의 컨텍스트에서 실행 줄일 수 있습니다.

관련 문제