2011-04-25 2 views
0

나는 일련의 이벤트를 보유하고있는 couchdb를 가지고 있습니다. 각 이벤트에는 소유자, ID, 발생한 시간 및 메시지 (이 운동에서는 중요하지 않은 다른 여러 가지 요소가 있음)가 있습니다. 나는 최근에 시간 순서대로 일어난 사건 목록을 원합니다. 나는이 질문을 통해 보았고, 감속기에서 첫 번째 메시지 (복잡한 키를 가지고있는 양식을 사용)를 유지하기 위해 뒤집어서 비교해 보았습니다.Couchdb map/reduce를 사용하여 스트림에서 첫 번째를 반환하고 시간순으로 정렬합니다.

불행히도 원하는 것은하지 않는 것 같습니다.

여기 내지도 기능

function(doc) { 
    var owner, id; 
    if (doc.owner 
     && doc.stream_id 
     && doc.message 
     && doc.receipt_time) 
    { 
     emit([doc.owner,doc.stream_id,doc.receipt_time], 
      { owner: doc.owner, 
      stream_id: doc.stream_id, 
      timestamp: doc.receipt_time, 
      message: doc.message 
      }); 
    } 
} 

그리고 내 진정한 = 다음

function(keys, values) { 
    var challenger, winner = null; 
    for (var a = 0; a < values.length; a++) { 
     challenger = values[a]; 
     if (! winner) { 
     winner = challenger; 
     } else { 
     if (winner.owner !== challenger.owner 
      && winner.trace_id !== challenger.trace_id) { 
      return null; 
     } else if (challenger.timestamp < winner.timestamp) { 
      winner = challenger; 
     } 
     } 
    } 
    return winner; 
} 

내가 함께? 하강 호출 기능 = 사실 & 그룹 줄일 & group_level = 2 각 스트림의 첫 번째 메시지를 얻을 수 그러나 시간에 따라 정렬되지는 않지만 소유자 및 stream_id는 이와 같이

{"rows":[ 
    {"key":["sam","a"], 
    "value": 
    {"owner":"sam","stream_id":"a","timestamp":1303754236482,"message":"foo"} 
    }, 
    {"key":["sam","b"], 
    "value": 
    {"owner":"sam","stream_id":"b","timestamp":1303752578476,"message":"bar"} 
    }, 
    {"key":["jim","j1"], 
    "value": 
    {"owner":"jim","stream_id":"j1","timestamp":1303625378839,"message":"stuff"} 
    }, 
    {"key":["bob","loblaw"], 
    "value": 
    {"owner":"bob","stream_id":"loblaw","timestamp":1303328396532,"message":"more stuff"} 
    }, 
    {"key":["anthony","foo"], 
    "value": 
    {"owner":"anthony","stream_id":"foo","timestamp":1303769699444,"message":"even more"} 
    } 
]} 

(최종 입력은 실제로 가장 최근의 시간입니다.)

그래서 내가 원하는 것은 최종보기가 현재의 것이지만 시간순으로 정렬 된 것입니다. 이것을 할 수있는 방법이 있습니까?

답변

0

정확하게 이해한다면 이벤트 컬렉션을 필터링하지 않고 주문할 수 있습니다. 그것이 맞다고 가정하면, 솔루션은 실제로 매우 간단하며 reduce 함수가 필요조차 없습니다. 맵 함수에서 방출 된 키는 먼저 키의 첫 번째 부분부터 먼저 뷰를 정렬 한 다음 나머지 부분을 처리하는 데 사용됩니다. 당신이 다음 receipt_time stream_id를 기준으로 정렬 할 경우 즉, 방출하는 통화는 다음과 같이 보일 것이다 :

emit([doc.stream_id,doc.receipt_time,doc.owner], doc.message); 

를 당연히, 대신 다음 stream_id_extension은, 키가 대신 [doc.receipt_time,doc.stream_id,doc.owner]을 것 receipt_time을 기준으로 정렬 할 경우. 이미 키에있는 값에 무엇이든 포함 할 필요가 없다고 생각합니다. 따라서 메시지의 값을 줄였습니다.

+0

나는 당신이 오해하고 있다고 생각합니다. 어느 소유자 + stream_id에 대해서도 수천 개의 메시지가있을 수 있습니다. 각 스트림에 첫 번째 메시지를 표시하고 타임 스탬프별로 순서를 지정하려고합니다. [owner, stream_id, receipt_time]을 주문한 다음 group_level 2와 내가 설명한 reduce 함수를 사용하여 소유자 및 stream_id에 의해 각 스트림의 첫 번째 메시지를 받지만 ** 시간에 따라 순서가 잘못되었습니다. 내가 receipt_time (ie, group_level 3)을 포함하면, 나는 모든 메시지를 얻는다, 그래서 그 목적을 이긴다. – Nym

+0

네가 맞아, 나는 오해했다. 나는 아직도 실제로 일할 수있는 더 쉬운 방법이있을 것이라고 생각하지만, 그것에 대해 생각해야 할 것입니다. 아마도 소파 전문가 중 한 명이 함께 와서 그 동안 답변을 제공 할 것입니다. –

0

음, 가장 쉬운 방법은 실제로 문제를 피하는 것입니다.

내가 방금 "start":true, 필드를 스트림에있는 첫 번째 문서에 추가 한 소프트웨어를 제어하기 때문에보기 기능은 그 값으로 이벤트를 방출합니다.

이것은 이전 데이터에 대해서는 알 수 없지만 대부분 최근 스트림을 확인하는 것이므로 괜찮습니다.

내가 시도한 또 다른 대안은 키가 [timestamp, owner, stream_id] 인보기에서 각 소유자 stream_id의 첫 번째 인스턴스를 보내는 목록 기능을 추가하는 것이 었습니다. 그러나 제한하는 경우 문제가 발생합니다. 최종 렌더링 된 목록을 제한하지 않고 원본보기이므로 여분의 키가 지금까지 가장 잘 작동합니다.)

원래 데이터로이를 수행 할 수있는 방법이 있는지 알고 싶습니다.

1

모든 메시지에 stream_created_at 타임 스탬프를 저장하십시오. 첫 번째 메시지의 경우 현재 시간을 가져갑니다. 스트림의 모든 다음 메시지에 대해 이전 메시지에서 복사합니다 (이 경우 stream_created_at_by_stream_id를 얻기위한보기를 만듭니다).

는 그런 방출 뷰를 생성 : 시간 순서를 동일한 스트림에서 그룹 메시지 보존됩니다 함께하면서

[doc.owner,doc.stream_created_at, doc.stream_id, doc.receipt_time] 

. stream.id는 두 스트림이 동시에 생성 될 때 서로 다른 스트림의 메시지가 섞이지 않도록합니다. 그리고 receipt_time은 시간별로 스트림의 메시지를 정렬합니다.

결국 결국 대화와 같은 Facebook을 받게됩니다. 그리고 당신은 어떤 reduce 함수도 전혀 필요로하지 않습니다.

관련 문제