2010-06-13 3 views
32

"SQL join"과 동일한 CouchDB를 찾고 있습니다.CouchDB에서 일대 다 "JOIN"을 수행하는 가장 좋은 방법

{ "type" : "el", "id" : "1", "content" : "first" } 
{ "type" : "el", "id" : "2", "content" : "second" } 
{ "type" : "el", "id" : "3", "content" : "third" } 

목록을 정의하는 하나 개의 문서가있다 : 내 예에서

목록 요소 CouchDB를 문서가

{ "type" : "list", "elements" : ["2","1"] , "id" : "abc123" } 

당신은 세 번째 요소는, 그것을 삭제 볼 수 있듯이 더 이상 목록에 포함되지 않습니다. 따라서 결과의 일부가되어서는 안됩니다. 이제는 올바른 순서를 포함한 콘텐츠 요소를 반환하는보기가 필요합니다.

결과가 될 수있다 : 그것은이어야하는 요소의 순서가 이미이 경우

{ "content" : ["second", "first"] } 

한다. 또 다른 가능한 결과 :

{ "content" : [{"content" : "first", "order" : 2},{"content" : "second", "order" : 1}] } 

내가지도 기능을 쓰기 시작 : 이것은 지금까지 내가 얻을 수있다

map = function (doc) { 
    if (doc.type === 'el') { 
    emit(doc.id, {"content" : doc.content}); //emit the id and the content 
    exit; 
    } 
    if (doc.type === 'list') { 
    for (var i=0, l=doc.elements.length; i<l; ++i){ 
     emit(doc.elements[i], { "order" : i }); //emit the id and the order 
    } 
    } 
} 

. 내 실수를 바로 잡고 감산 기능을 쓸 수 있습니까? 세 번째 문서는 결과의 일부가 아니어야 함을 기억하십시오.

물론 다른지도 기능을 작성할 수도 있습니다. 그러나 문서의 구조 (하나의 정의 요소 문서와 각 항목에 대한 입력 문서)는 변경할 수 없습니다.


편집 : 그는이 짧은 작업을 수행하는 방법에 대해 설명 그의 대답에 JasonSmith의 의견을 놓치지 마세요.

답변

50

고맙습니다! 이것은 CouchDB 0.11's new features을 과시하는 좋은 예입니다!

fetch 관련 데이터 기능을 사용하여보기에서 문서를 참조해야합니다. 선택적으로 더 편리한 JSON의 경우 _list 함수를 사용하여 결과를 정리하십시오. 자세한 내용은 Couchio's writeup on "JOIN"s을 참조하십시오.

  1. 는 첫째로, 당신은 당신의 el 문서의 고유성 contstraint이 : 여기

    는 계획이다. 중 2 개가 id = 2 인 경우 문제가 발생합니다. id 인 경우 _id 필드 대신 사용해야합니다. CouchDB는 고유성을 보장하지만 나머지는이 ID로 문서를 가져 오기 위해 _id이 필요합니다. 문서를 변경하면 _id 절대적으로 불가능 사용하는 경우
    { "type" : "el", "_id" : "1", "content" : "first" } 
    { "type" : "el", "_id" : "2", "content" : "second" } 
    { "type" : "el", "_id" : "3", "content" : "third" } 
    

    , 당신은 임시 데이터베이스에 그것을 삽입 다시 다음 emit(doc.id, doc)에 간단한보기를 만들 수 있습니다. 이 경우 id_id으로 변환되지만 약간의 복잡성이 추가됩니다.

  2. 뷰는 자신의 콘텐츠와 [list_id, sort_number]에 키가 {"_id": content_id} 데이터에 "덩어리"목록을 방출한다.

    function(doc) { 
        if(doc.type == 'list') { 
        for (var i in doc.elements) { 
         // Link to the el document's id. 
         var id = doc.elements[i]; 
         emit([doc.id, i], {'_id': id}); 
        } 
        } 
    } 
    

    올바른 순서로 el 문서의 간단한 목록이 있습니다. 특정 목록 만 보려면 startkeyendkey을 사용할 수 있습니다.

    curl localhost:5984/x/_design/myapp/_view/els 
    {"total_rows":2,"offset":0,"rows":[ 
    {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"}}, 
    {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"}} 
    ]} 
    
  3. include_docs=true으로 el 내용, 질의를 얻으려면. _id의 마법을 통해 el 개의 문서가로드됩니다.

    curl localhost:5984/x/_design/myapp/_view/els?include_docs=true 
    {"total_rows":2,"offset":0,"rows":[ 
    {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","0"],"value":{"_id":"2"},"doc":{"_id":"2","_rev":"1-4530dc6946d78f1e97f56568de5a85d9","type":"el","content":"second"}}, 
    {"id":"036f3614aeee05344cdfb66fa1002db6","key":["abc123","1"],"value":{"_id":"1"},"doc":{"_id":"1","_rev":"1-852badd683f22ad4705ed9fcdea5b814","type":"el","content":"first"}} 
    ]} 
    

    이 정보는 이미 필요한 모든 정보입니다. 클라이언트가 유연한 경우이 JSON에서 정보를 구문 분석 할 수 있습니다. 다음 (선택 사항) 단계는 필요한 항목과 일치하도록 간단히 형식을 다시 지정합니다.

  4. _list 기능을 사용하면 간단히보기 출력을 다시 포맷 할 수 있습니다. 사람들은 XML 또는 HTML 출력에 사용하지만 JSON을보다 편리하게 만들 것입니다.

    function(head, req) { 
        var headers = {'Content-Type': 'application/json'}; 
        var result; 
        if(req.query.include_docs != 'true') { 
        start({'code': 400, headers: headers}); 
        result = {'error': 'I require include_docs=true'}; 
        } else { 
        start({'headers': headers}); 
        result = {'content': []}; 
        while(row = getRow()) { 
         result.content.push(row.doc.content); 
        } 
        } 
        send(JSON.stringify(result)); 
    } 
    

    결과가 일치합니다. 프로덕션에서 원하는 목록을 지정하려면 startkeyendkey이 필요합니다.

    curl -g 'localhost:5984/x/_design/myapp/_list/pretty/els?include_docs=true&startkey=["abc123",""]&endkey=["abc123",{}]' 
    {"content":["second","first"]} 
    
+3

말씀이 철저한입니다. 좋은 직업 jhs! –

+2

오해의 소지가 있습니다. 실제로 # 2 단계는 완벽한 솔루션입니다. 그렇지만 자세한 배경 요구 사항과 클라이언트 측에서 편리함을 추가 할 수있는 옵션이 있습니다. – JasonSmith

+1

CouchIO URL이 변경되었습니다. 동일한 기사의 새 URL은 다음과 같습니다. http://couchio.tumblr.com/post/446015664/whats-new-in-apache-couchdb-011-part-two – Bdoserror