2011-11-24 2 views
7

CouchApp (미들웨어 없음)에 대한 최선의 방법을 결정하려고합니다. 내 생각과 유사하기 때문에 CouchDB에 스택 오버 플로우 페이지가 저장되어 있다고 가정한다. 본질적으로 그것은 맨 위에있는 실제 질문, 답변 및 커밋으로 구성됩니다. 그것들은 기본적으로 3 개의 레이어입니다.CouchDB : 단일 문서 대 "합류"문서

두 가지 저장 방법이 있습니다. 데이터의 적절한 JSON 표현을 포함하는 단일 문서 내에서 또는 항목의 각 부분을 별도의 문서에 저장하여 나중에보기와 결합합니다 (http://www.cmlenz.net/archives/2007/10/couchdb-joins과 유사)

이제 두 방법 모두 괜찮을 수 있습니다. 둘 다 현재의 관점에서 거대한 불리한 점이 있습니다. signle 엔티티가 충돌을 일으킬 수 있으므로 바쁜 문서 (여러 사용자를 통한 많은 변경이 예상 됨)를 저장합니다. 사용자 A가 자신의 변경 내용을 문서에 저장하면 사용자 B는 업데이트를 입력 한 후에 충돌 오류를 받게됩니다. 다시 시도하기 전에 문서를 다시 다운로드하여 사용자의 지식없이이 문제를 해결할 수 있다고 상상할 수 있습니다.

Multi User Update problem

그러나 문서가 오히려 큰 경우 ? 나는 많은 사람들이 동시에 문서를 업데이트하기 때문에 재시도 프로세스가 여러 번 발생해야하는 경우, 시간이 지남에 따라 오히려 날아 오르면 저장 프로세스에 상당한 지연을 초래할 것입니다.

제가보기에는 또 다른 문제는 편집입니다. 모든 사용자는 자신의 기고문을 편집 할 수 있어야합니다. 이제는 하나의 문서 내에 저장되는 경우 견고한 인증 처리기를 작성하기가 어려울 수 있습니다.

이제 여러 문서 접근 방식을 살펴 보겠습니다. 질문, 답변 및 의견은 자체 문서에 저장됩니다. 장점 : 문서의 실제 소유자 만 충돌을 일으킬 수 있으며 너무 자주 발생하지는 않습니다. 오히려 전체적으로 작은 요소이기 때문에 재판매는 시간이 많이 걸리지 않을 것입니다. 또한 auth 루틴은 매우 쉽게 구현해야합니다.

이제 단점이 있습니다. 단일 문서는 실제로 쿼리하고 표시 할 수 있습니다. 정렬되지 않고 구조화 된 형식으로 전체 항목을 포함하는 JSON 객체를 100 % 사용할 준비가 된 실제 뷰를 얻지 못했기 때문에 정렬되지 않은 스 니펫을 여러 개 배치하는 것은 지저분한 일처럼 보입니다.

enter image description here

은 내가 실제 문제를 의사 소통을 할 수있었습니다 바랍니다. 나는 어느 솔루션이 나에게 더 적합 할 지 결정하려고하는데, 어떤 문제를 극복하기가 더 쉽습니다. 첫 번째 솔루션이 스토리지 및 쿼리 측면에서 더 예쁜 솔루션이라고 상상해보십시오. 그러나 두 번째는보다 나은 키 관리를 통해 해결할 수있는보다 실용적인 솔루션입니다 (아직 키의 원리가 아님).

사전에 당신의 도움 :) 두 번째 옵션을

답변

8

이동 주셔서 대단히 감사합니다. 갈등을 처리하는 것보다 훨씬 쉽습니다. 여기에 데이터를 구조화하는 방법을 몇 가지 예제 문서는 다음과 같습니다

{ 
    _id: 12345, 
    type: 'question', 
    slug: 'couchdb-single-document-vs-joining-documents-together', 
    markdown: 'Im tryting to decide the best approach for a CouchApp (no middleware). Since there are similarities to...' , 
    user: 'roman-geber', 
    date: 1322150148041, 
    'jquery.couch.attachPrevRev' : true 
} 
{ 
    _id: 23456, 
    type: 'answer' 
    question: 12345, 
    markdown: 'Go with your second option...', 
    user : 'ryan-ramage', 
    votes: 100, 
    date: 1322151148041, 
    'jquery.couch.attachPrevRev' : true 
} 
{ 
    _id: 45678, 
    type: 'comment' 
    question: 12345, 
    answer: 23456, 
    markdown : 'I really like what you have said, but...' , 
    user: 'somedude', 
    date: 1322151158041, 
    'jquery.couch.attachPrevRev' : true 
} 

해당 문서에 첨부 파일이 편집 된 것으로 나는 이전 버전을 저장하는 것, 각각의 개정을 저장합니다. couchdb에 jquery 클라이언트를 사용하면 jquery.couch.attachPrevRev = true를 추가하여 무료로 얻을 수 있습니다.Versioning docs in CouchDB by jchris

fullQuestion : { 
    map : function(doc) { 
     if (doc.type == 'question') emit([doc._id, null, null], null); 
     if (doc.type == 'answer') emit([doc.question, doc._id, null], null); 
     if (doc.type == 'comment') emit([doc.question, doc.answer, doc._id], null) ; 
    } 
} 

같은보기 만들기를 참조하십시오 그리고이

http://localhost:5984/so/_design/app/_view/fullQuestion?startkey=['12345']&endkey=['12345',{},{}]&include_docs=true 

(참고 :이 쿼리를 URL 인코딩하지 않은,하지만 더 읽을 수)과 같은 뷰 쿼리

이렇게하면 페이지를 작성하는 데 필요한 질문과 관련된 모든 관련 문서가 제공됩니다. 유일한 것은 날짜별로 정렬되지 않는다는 것입니다. 클라이언트 측 (자바 스크립트에서)에서 정렬 할 수 있습니다.

편집 : 여기에 뷰 및 쿼리

도메인을 기반으로, 당신은 몇 가지 사실을 알고에 대한 대체 옵션입니다. 질문이 있기 전에는 답이 없습니다. 대답이 있기 전에는 대답에 대한 설명이 없습니다. 그래서 사물의 질서를 존중, 더 빨리 표시 페이지를 만들 수 있습니다보기를 만들 수 있습니다 :

fullQuestion : { 
    map : function(doc) { 
     if (doc.type == 'question') emit([doc._id, doc.date], null); 
     if (doc.type == 'answer') emit([doc.question, doc.date], null); 
     if (doc.type == 'comment') emit([doc.question, doc.date], null); 
    } 
} 

이 함께 모든 관련 문서를 유지하며, 날짜별로 정렬을 유지한다. 다음은 샘플 쿼리입니다.

http://localhost:5984/so/_design/app/_view/fullQuestion?startkey=['12345']&endkey=['12345',{}]&include_docs=true 

그러면 가장 오래된 것부터 가장 최신의 순서로 필요한 모든 문서가 반환됩니다. 이제이 같은 부모 개체가 자식들 앞에 될 것으로 알고, 그 결과를 압축 할 수 있습니다

function addAnswer(doc) { 
    $('.answers').append(answerTemplate(doc)); 
} 

function addCommentToAnswer(doc) { 
    $('#' + doc.answer).append(commentTemplate(doc)); 
} 

$.each(results.rows, function(i, row) { 
    if (row.doc.type == 'question') displyQuestionInfo(row.doc); 
    if (row.doc.type == 'answer') addAnswer(row.doc); 
    if (row.doc.type == 'comment') addCommentToAnswer(row.doc) 
}) 

을 그럼 당신이 어떤 클라이언트 측 정렬을 수행 할 필요 없다.

희망이 도움이됩니다.

+0

안녕하세요! 귀하의 상세하고 이해할 수있는 답변을 주셔서 감사합니다. 너는 아직 내가 모르는 것들을 말해 줬어. 나는 두 번째 옵션의 첫 번째 버전을 다소 빠르게 구현했지만 아직 입력 내용을 기반으로 조정할 것입니다. 고마워요! :) –