2009-11-04 17 views
6

Basit bir örnek belirteyim: Sipariş ve Alışveriş Sepetiniz var. Bunu devam ettirmeyi düşündüğüm yollardan biri, bir Sipariş belgesini ve bir Sepet belgesini kaydetmektir. Sipariş belgesinde, ilgili Sepet belgesinin UUID değeri olan "alışveriş sepeti" adında bir alan olabilir. Bunu yapmanın başka bir yolu da, bir Sipariş belgesini, tüm Sepetteki bir ilişkisel dizi içeren "alışveriş sepeti" alanıyla kaydetmek. Diğer bir deyişle, Sepeti açıkça bağımsız bir belge olarak kaydetmek yerine, Sepetim belgesini Sipariş belgesine yerleştirdim.CouchDB'de yabancı anahtarların uygulanmasının deyimsel yolu nedir?

Daha sonra bir Cart'ın kalıcı olması gerektiğine karar verirsek, geri dönen bir kullanıcı yarı mamul Cart'ı oturumları boyunca beklerken bulacaktır? Daha sonra, her iki yöntemi bir araya getirebileceğimizi, Cart'ı tamamlanmamış halde ayrı tuttuğunu ve son haline getirildiğinde/satın alındığında Sipariş belgesine gömebileceğimizi hayal ediyorum.

Her iki yöntem de çalışacaktır, ancak CouchDB'nin yabancı anahtar kısıtlamalarına sahip olmamasından endişeleniyorum; İlk yöntemde Cart belgesi silinebilir ve size bozuk bir veri kümesi bırakabilir.

Hangi yöntemin kullanılacağına nasıl karar verirsiniz? Bu yöntemlerden biri CouchDB'ye daha aptalca mıdır? Kaçırdığım yöntemler var mı?

CouchDB'ye yeni yaşıyorum, bu yüzden avantajları/dezavantajları az çok normalleştirilmiş bir yapıya sahip olmamı görmek benim için zor.

cevap

4

Diğer taraftan, bire bir değillerse, karmaşık bir anahtar kullanarak, birleştirme yapmak için görünüm harmanlamasını kullanabilirsiniz.

function(doc) { 
    if (doc.type == 'order') { 
    emit([doc.cartid, 1], doc); 
    } else if (doc.type == 'cart') { 
    emit([doc.id, 0], doc); 
    } 
} 

Dokümanlar, kartuştan sonra gelen siparişlerle birlikte cartid tarafından toplanacaktır. Uygulama kodunuz bu akışa kolayca katılabilir ve başlangıç ​​ve bitiş tuşlarını kullanarak belirli bir kartuşla sorgulayabilirsiniz. Harmanlama kuralları için bkz: View Collation

Ayrıca bunları birleştirmek için de bir azaltma kullanabilirsiniz. Bunun gibi işlev azaltmak

function(doc) { 
    if (doc.type == 'order') { 
    emit([doc.cartid, 1], {cartid: doc.cartid, orders: [doc]}); 
    } else if (doc.type == 'cart') { 
    emit([doc.id, 0], {cartid: doc.id, orders: [], cart: doc); 
    } 
} 

ve ekleyin:

Sadece bu harita işlevi değiştirmek

function(keys, values) { 
    var out = {cartid: null, orders: [], cart: null}; 
    for (idx in values) { 
    var doc = values[idx]; 
    out['cartid'] = doc.cartid; 
    if (doc.cart) { out['cart'] = doc.cart }; 
    for (idx2 in doc.orders) { 
     out.orders.push(doc.orders[idx2]); 
    } 
    } 
    return out; 
} 

Bu sepeti başına tek bir belge dönecektir hangi edecek bir cartid, bir dizi sipariş belgeleri ve bir sepet belgesi.

Yukarıdaki kodda hatalar varsa özür dileriz ancak bunları denemek için kullanışlı bir couchdb test örneğim yok. Genel fikri almalı ve CouchDB wiki daha fazla ayrıntıya sahip olmalı.

0

Sipariş ve El Arabası nesneleri birebir bir ilişkiye sahipse (bu şekilde kulağa nasıl geliyor), o zaman ikinci yaklaşım en mantıklıdır ... yalnızca ilişkili nesneleri bir arada bulundurun. Bu, aradığınız veri bütünlüğünü verir ve basitleştirir ;-)

İlgili konular