2012-07-01 3 views
0

mongodb에서 mapreduce를 사용하여 PageRank를 실행하려고합니다.mongodb에서 PageRank 계산하기

내 문서는이 형식으로되어 있습니다 :

{ 
     "_id" : "u: 10000", 
     "value" : [ 
       [ 
         "u: 10000", 
         "s: 985272", 
         1 
       ], 
       [ 
         "s: 985272", 
         "u: 10000", 
         1 
       ], 
       [ 
         "u: 10000", 
         "s: 303770", 
         1 
       ], 
       [ 
         "s: 303770", 
         "u: 10000", 
         1 
       ] 
     ] 
} 

는 지금은 첫 번째 단계는 키를 기준으로 링크를 수집하는 것입니다 생각합니다. 그러나 문서 당 여러 개의 아웃 바운드 링크가 있습니다. (이들은 모두 양방향으로 발생합니다). 여기

내지도하고 기능을 감소 :

m = function() { 
    for (var i = 0; i < this.value.length; i++){ 
     var out = {}; 
     out.out = this.value[i][1]; 
     out.weight = this.value[i][2]; 
     emit(this.value[i][0], [out]); 
    } 
} 

r = function(key, values){ 
    var result = { 
     value: [] 
    }; 
    values.forEach(function(val) { 
    result.value.push({out: val.out, weight: val.weight}); 
    }); 
    return result; 
} 

문제는 내가 문서에 여러 배출량을 생산하고 방출하는 확실하지 않다입니다. 내가 같은 결과를 얻을으로 :

{ 
     "_id" : "s: 1000082", 
     "value" : [ 
       { 
         "out" : "u: 37317", 
         "weight" : 1 
       } 
     ] 
} 

을 나는 문서 당 여러 항목을 기대합니다.

누구든지 아이디어가 있습니까? 도와 주시면 감사하겠습니다!

편집 :

나는 완전히 만족하지 않다, 예를 how do things like this work 하시나요?. reduce 결과는 emit 출력과 전혀 같지 않습니다.

+0

필드 값이 무엇인지 명확히 할 수 있습니까? "s"와 "u"등 무엇입니까? –

+0

그들은 이드와 함께 문서 (웹 페이지)의 단지 다른 유형입니다 ... – toofarsideways

+0

아래 답변은 정확합니다 - 방출 된 값에 더 많은 필드를 추가하는 데 문제가 있다면, 나는 새로운 질문을 시작하는 것이 좋습니다. –

답변

3

배열을 매핑하지 않지만 reduce가 배열로 푸시하려고하는 것이 문제입니다.

"out"및 "weight"쌍의 배열로 각 키 맵을 가져 오려면 해당 배열을 포함하는 배열을 내 보내야하며 줄이면 배열을 함께 연결해야합니다. 의미

기억 the structure of the object returned by the reduce function must be identical to the structure of the map function's emitted value.

당신의지도를 방출 (키, 값) "값"의 구조는 결과로 함수가 반환을 줄일 것을의 구조와 동일해야합니다.

function() { 
    for (var i = 0; i < this.value.length; i++) { 
     key = this.value[i][0]; 
     value = {value:[{out:this.value[i][1], weight:this.value[i][2]}]}; 
     emit(key, value); 
    } 
} 

과 :

그 값이 문서의 배열을 각각 갖는 필드 "밖으로"현장 "무게"입니다 필드 "값"을 가진 문서가 그래서 당신이 당신의지도 기능을 변경하는 경우

(그냥은 각 키에 전달되는 것을 연결 한 이후) 위에서 방출 값과 동일한 구조를 가지고 결과를 구축이로 감소 기능 :

function (key, values) { 
    result = {value:[]}; 
    for (var i in values) { 
     result.value = values[i].value.concat(result.value); 
    } 
    return result; 
} 

그런 다음 다시 기대하고 무엇을 얻을 것이다 .

{ 
    "_id" : "s: 303770", 
    "value" : { 
     "value" : [ 
      { 
       "out" : "u: 10000", 
       "weight" : 1 
      } 
     ] 
    } 
} 
{ 
    "_id" : "s: 985272", 
    "value" : { 
     "value" : [ 
      { 
       "out" : "u: 10000", 
       "weight" : 1 
      } 
     ] 
    } 
} 
{ 
    "_id" : "u: 10000", 
    "value" : { 
     "value" : [ 
      { 
       "out" : "s: 303770", 
       "weight" : 1 
      }, 
      { 
       "out" : "s: 985272", 
       "weight" : 1 
      } 
     ] 
    } 
} 
+0

모든 문서가 축소 단계를 거쳐야합니까?첫 번째 "값"지도에 순위 값을 추가했기 때문에 묻습니다 만 일부 문서에만 나타납니다. 'r = 함수 (키, 값) { result = {rank : 1.0, value : []}; for (값이 var i) { result.value = values ​​[i] .value.concat (result.value); } 반환 결과; }' – toofarsideways

+0

모든 문서가 매핑됩니다. reduce 함수가 반환하는 것과 동일한 형식을 맵에서 내보내야합니다. –

+0

잠깐, 그럼이 작품은 어떻게 되나요? -> http://kylebanker.com/blog/2009/12/mongodb-map-reduce-basics/. reduce 결과는 emit 출력과 전혀 같지 않습니다. – toofarsideways