2013-06-26 3 views
0

나는 Voting with Atomic Operators 글을 읽었습니다. 이 기사에서 voters 필드는 ObjectId의 배열입니다. 그러나 나는 다음과 같은 형식으로 포함 된 문서의 배열로 voters를 저장하고 싶습니다 :MongoDB - "원자 연산자로 투표"에 대한 임베드 버전

{ 
    user: ObjectId, 
    date: Date, 
    isDownvote: Boolean, // If false, it's an upvote. 
} 

사용자가 찬성 투표하거나 스택 오버플로가 제공하는 투표 시스템과 같은 게시물을 downvote 수 있습니다. 사용자가 게시물을 찬성 투표 할 때, 예를 들어, 경우 고려해야 할이 있습니다 : 사용자에 의한 downvote이 이미 존재

  • 경우, 투표의 isDownvotefalse에 업데이트됩니다.
  • isDownvote이 (가) false 인 새 투표를 밀어 넣으십시오.

이 투표 형식으로 단일 쿼리에서 투표를 푸시/풀링하려면 어떻게해야합니까?

답변

1

완전히 원자 적으로이 일을하는 또 다른 방법은 다음과 같습니다

db.posts.update({'_id':post_id}, { 
    '$pull': {'votes.user':ObjectId}, 
    '$addToSet': {votes: { 
     user: objectId, 
     date: Date, 
     isdownvote: isdownvote 
    }} 
}) 

은 이미 말했다, 하위 문서에 대한 upsert 없다 그래서이 사기꾼의 종류와 이전 투표를 삭제하고 다시 작성합니다. date 필드는 여전히 좋아야합니다. 사용자가 다시 투표하면 date 필드가 사용자가 투표 한 마지막 시간으로 변경되어야하므로 그 부분이 의미가 있습니다.

+0

고마워. 이것은 답이되어야합니다. [원자 연산자를 사용하여 투표] (http://cookbook.mongodb.org/patterns/votes/) 문서의 쿼리도 카운터를 업데이트하지만이 경우 단일 쿼리에서이를 수행 할 방법이 없다고 생각합니다. –

+0

@TrantorLiu 흠, 아무도이 경우에도 두 개의 쿼리를 필요로하지 않습니다. – Sammaye

1
$push : { voters : { 
    user: ObjectId, 
    date: Date 
}} 
+0

죄송합니다. 질문을 편집했습니다. 새로운 필드'isDownvote'를 추가했습니다. –

+0

이것이 단일 쿼리 –

+0

에서 수행 될 수 있을지 의심 스럽습니다. 임베디드 문서에는 'upsert'가 없습니다. '$ addToSet'은 존재하지 않는다면 subdoc 만 추가하지만, 존재하지 않는 경우에는 subdoc을 갱신하지 않습니다. –

관련 문제