2011-11-24 33 views
7

Bir CouchApp (ara katman yazılımı) için en iyi yaklaşımı karar vermeye çalışıyorum. Fikrim ile benzerlikler bulunduğundan, bir CouchDB'de depolanmış bir stackoverflow sayfamız olduğunu varsayalım. Özünde, üst, cevaplar ve kuyruklu yıldızlar ile ilgili asıl sorudan oluşur. Bunlar temelde üç katman.CouchDB: Tek belge "birlikte" belgelere "birlikte"

İki yolu saklamak için vardır. Verilerin uygun bir JSON temsilini içeren tek bir belge içinde veya girişin her bir parçasını daha sonra bir görünümle birleştiren ayrı bir belgede saklayın (buna benzer: http://www.cmlenz.net/archives/2007/10/couchdb-joins)

Her iki yaklaşım da iyi olabilir. Ancak her ikisinin de şu anki bakış açımdan devasa olumsuz etkileri var. Meşgul bir belgenin saklanması (bir çok kullanıcının birden fazla kullanıcı tarafından değiştirilmesi beklenir), bir tarafın çatışmaya neden olması gibi. A kullanıcısı değişikliklerini belgede saklarsa, B kullanıcısı güncellemeyi yazdıktan sonra çakışma hatası alır. Tekrar denemeden önce belgeyi yeniden indirerek kullanıcı bilgisi olmadan bunu düzeltmeyi hayal edebiliyorum.

Multi User Update problem

Ama ne belge oldukça büyükse ? Bir kayıt işlemi üzerinde oldukça dikkat çekici bir gecikme yaratacak olan zaman içinde oldukça şişirilmiş olmaları dışında, özellikle bir çok kullanıcının aynı anda bir dokümanı güncellemesi nedeniyle yeniden deneme sürecinin birden çok kez gerçekleşmesi gerekiyorsa.

Gördüğüm başka bir sorun ise düzenleme. Her kullanıcının katkılarını düzenlemesine izin verilmelidir. Şimdi, eğer bir belge içinde saklanıyorlarsa, katı bir auth işleyicisi yazmak zor olabilir.

Şimdi birden çok belge yaklaşımına bakalım. Soru, Cevaplar ve Yorumlar kendi dokümanlarında saklanacaktır. Avantaj: sadece belgenin asıl sahibi çatışmalara neden olabilir, çok sık olmayacak bir şey. Tamamen küçük unsurlar olmakla, yeniden yükleme yapmak fazla zaman almaz. Ayrıca, auth rutininin gerçekleştirilmesi oldukça kolay olmalıdır.

Şimdi burada olumsuzluk var. Tek bir belgeyi sorgulamak ve görüntülemek gerçekten kolaydır. Düzenli ve yapılandırılmış bir biçimde tüm öğeyi içeren JSON nesnesini kullanmak için% 100 hazır sunmam için gerçek görünümü elde etmediğim için, etrafa serpiştirilmiş çok sayıda parçacığı dağınık bir şey gibi görünüyor.

enter image description here

ben gerçek sorunu iletişim kurabilmesi oldum umarım. Hangi çözümün benim için daha uygun olacağına karar vermeye çalışıyorum, ki bu da üstesinden gelinmesi kolaylaşır. İlk çözümün depolama ve sorgulama açısından daha güzel olmasını hayal ediyorum, ancak ikincisi, daha iyi bir anahtar yönetim anlayışıyla çözülebilen daha pratik olanı (tamamen anahtarların ilkesine bağlı değilim).

önceden Yardımlarınız :) ikinci seçeneği ile

cevap

8

Go için çok teşekkür ederim. Çatışmalarla uğraşmaktan çok daha kolay. İşte verileri nasıl yapılandırabileceğinize bazı örnek dokümanlar şunlardır:

{ 
    _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 
} 

doküman üzerinde ekleri düzenlenmekte olan ben eski sürümleri depolamak istiyorum, her birinin revizyonları saklamak için. Couchdb için jquery istemcisini kullanırsanız, jquery.couch.attachPrevRev = true ekleyerek ücretsiz olarak edinebilirsiniz.Versioning docs in CouchDB by jchris

bu

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) ; 
    } 
} 

gibi bir görünüm oluşturma Bkz Ve bu

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

(Not: Ben bu sorguyu kodlanmış URL'yi değil, ama daha okunabilir) gibi görünüm sorgulamak

Bu, sayfayı oluşturmanız gerekeceği sorusuyla ilgili tüm belgeleri alacaktır. Tek şey, tarihe göre sıralanmayacaklarıdır. Onları istemci tarafında (javascript'te) sıralayabilirsiniz.

DÜZENLEME: Burada görünümü ve sorguda

etki alanınız dayanarak, bazı gerçekler biliyoruz için alternatif bir seçenektir. Bir sorunun varlığından önce bir cevabın bulunamadığını ve bir cevap bulunmadan önce bir cevabın yorumunun bulunamayacağını biliyorsunuz. Yani şeylerin sıraya uyarak daha hızlı ekran sayfası oluşturmak için hale getirebileceğini bir görünüm yapalım:

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); 
    } 
} 

Bu arada tüm ilgili dokümanlar tutacak ve tarihe göre sıralı tutun. İşte bu en eski en yeni emri ihtiyacınız olacak tüm belgeler, geri alacak bir örnek sorgu

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

olduğunu. Artık bu gibi ebeveyn nesneler çocuk olanlar önce olacağını bilerek sonuçları üzerinden zip yapabilirsiniz:

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) 
}) 

Öyleyse herhangi bir istemci tarafı sıralamayı gerçekleştirmek zorunda değilim.

Bu yardımcı olur umarım.

+0

Merhaba Ryan! Detaylı ve anlaşılır cevaplarınız için çok teşekkürler. Henüz bilmediğim bazı şeyleri söyledin. İkinci seçeneğin ilk sürümünü oldukça hızlı bir şekilde uygulayabildim, ancak girişinize göre ayarlayacağım. Çok teşekkürler! :) –