2011-02-28 1 views
4

Postgres의 Distinct와 비슷한 기능을 찾고 있습니다.MongoDB, 컬렉션의 각 user_id에 대한 최신 문서를 반환하십시오.

상태가 텍스트이고 날짜가 날짜 인 문서 모음 {user_id, current_status, date}이 있습니다. mongo 주위에 내 머리를 감싸고 일을하는 가장 좋은 방법에 대한 느낌을 얻는 초기 단계.

mapreduce가 가장 좋은 해결책이되고지도가 모두 나오고 줄이면 최신 기록을 유지합니까 아니면 미스터를 꺼내지 않고 솔루션이 내장되어 있습니까?

답변

0

distinct command이 있지만, 내가 필요한 것이 확실하지 않습니다. Distinct는 일종의 "쿼리"명령이며 사용자가 많으면 실시간이 아닌 데이터를 롤업하려고 할 것입니다.

지도 축소는 아마도 여기에 갈 수있는 한 가지 방법 일 것입니다.

지도 단계 :key은 단순히 ID입니다. value은 다음과 같을 것입니다 : {current_status:'blah',date:1234}.

줄이기 단계 : 값 배열이 있으면 가장 최근의 값을 가져 와서 만 반환합니다.

이 작업을 최적으로 수행하려면 1.8.0의 새로운 기능을보고 싶을 것입니다. "re-reduce" feature. 전체 상태 수집을 다시 처리하는 대신 새 데이터 만 처리 할 수 ​​있습니다.

이 작업을 수행 할 수있는 다른 방법은 "가장 최근의 '컬렉션을 구축하고 상태가 컬렉션에 삽입 넥타이를하는 것입니다. 따라서 사용자의 새로운 상태를 삽입하면 "가장 최근의"상태로 업데이트됩니다.

이 기능의 중요성에 따라 두 가지 작업을 모두 수행 할 수 있습니다.

+0

감사합니다. 이러한 접근 방식 모두를 살펴볼 가치가 있다고 생각합니다. 특히 재 감축하는 것이 좋습니다. – Peck

+0

가장 최근의 콜렉션 접근 방식에 대해 생각해 보면 삽입 프로세스에 많은 오버 헤드가 추가되는 것처럼 보입니다. 어쨌든 mongo와 관련된 이유 중 일부 였기 때문에 피하고 싶습니다. 각 ID에 대해 삽입하는 ID로 상태를 검색/제거해야합니다. 이 색인이 붙은 컬렉션과 더 작은 컬렉션 이후로는 빠르지는 않지만 mongo는 삭제를 위해 전체 컬렉션을 잠그는 "문제"가 있습니다. 그렇게하는 것이 큰 타협점이 될 수있는 것처럼 보입니다. – Peck

+0

당신은 매우 빠르게 될'upsert'을 할 수 있습니다. 'upsert'는 * "존재하는 업데이트가있을 경우 다른 것을 만듭니다"*입니다. 따라서 삭제 나 추가 쿼리가 없습니다. JS에서는 다음과 같은'db.most_recent.업데이트 ({_ id : user_id}, {status : "blah"}, false, true)', 언어 드라이버에서 "upsert"를 확인하십시오. –

0

잘 작동하는 것 같은 현재 솔루션.

map = function() {emit(this.user.id, this.created_at);} 

//We call new date just in case somethings not being stored as a date and instead just a string, cause my date gathering/inserting function is kind of stupid atm 

reduce = function(key, values) { return new Date(Math.max.apply(Math, values.map(function(x){return new Date(x)})))} 


res = db.statuses.mapReduce(map,reduce); 
0

특정 키에 집계 또는 키 집합 할 수있는 씨 - 바로 가기의 일종 인 group 명령을 사용하는 것 같은 결과를 얻을 수있는 또 다른 방법. 귀하의 경우에는 는 다음과 같이 읽을 것입니다 : 당신이 사용자의 다소 작은 고정 된 금액이없는 경우

db.coll.group({ key : { user_id: true }, 
       reduce : function(obj, prev) { 
          if (new Date(obj.date) < prev.date) { 
          prev.status = obj.status; 
          prev.date = obj.date; 
          } 
         }, 
       initial : { status : "" } 
}) 

그러나, 나는 강력하게 더 나은 솔루션은 이전에 제안 될 것이다만을 포함하는 분리 수거를 유지하기 위해 있다고 생각 각 사용자에 대한 최신 상태 메시지.

+1

그룹을 제안 해 주셔서 감사합니다. 그러나 그룹이 샤딩과 함께 사용할 수 없다면, 피할 해결책이 있습니다. – Peck