2010-10-18 13 views
6

Aşağıdaki gibi durumlarda bir IN yan tümcesiyle pahalı bir sorgulama yapmaktan kaçınmanın zekice bir yolu var mı?AppEngine (python) öğesinde IN sorguları ile alt sorguları en aza indirgeme

Bir Facebook uygulaması oluşturmak için Google App Engine kullanıyorum ve bir noktada (belli ki) belirli bir kullanıcının facebook arkadaşlarından birine ait olan tüm varlıkları almak için veri deposunu sorgulamanız gerekiyor.

varsayalım ben gibi modellenmiş kuruluşların bir çift:

class Thing(db.Model): 
    owner = db.ReferenceProperty(reference_class=User, required=True) 
    owner_id = db.StringProperty(required=True) 
    ... 

ve ben Facebook belirli bir kullanıcının arkadaş listesini almak için sorgu Bir noktada

class User(db.Model): 
    id = db.StringProperty(required=True) 
    ... 

ve ben gerek Aşağıdaki sorguyu gerçekleştirin:

Bunu yapsaydım, AppEngine her biri için bir alt sorgu gerçekleştirir d friend_ids'da, muhtemelen herhangi bir sorgunun üretebileceği alt sorguların maksimum sayısını aşıyor (30).

Bunu yapmanın daha iyi bir yolu var mı (yani sorgu sayısını en aza indirgemek)? Veri deposunu kullanarak hiçbir ilişki ve birleşimin olmadığını anlıyorum, ancak özellikle işleri kolaylaştırmak için User veya Thing sınıfına yeni alanlar eklemeyi düşünürdüm.

cevap

5

ben zarif bir çözüm var sanmıyorum, ama bu deneyebilirsiniz:, kullanıcı modeli üzerinde

anahtar adı olarak Facebook kimliğini kullanın ve bir ListProperty şeylerin her kullanıcının listesini depolar.

class Thing(db.Model): 
    ... 

class User(db.Model): 
    things = db.ListProperty(db.Key) 
    ... 

Varlık oluşturma böyle gider:

user = User.get_or_insert(my_facebook_id) 

thing = Thing() 
thing.put() 

user.things.append(thing.key()) 
user.put() 

Alım 2 sorguları sürüyor: Brett Slatkin tarafından

friends = User.get_by_key_name(friend_ids) 
thing_keys = [] 

for friend in friends: 
    thing_keys.extend(friend.things) 

things = db.get(thing_keys) 
+0

+1 Başka bir seçenek Çocukların Kullanıcıları Kullanmasını sağlamak için belirli bir türden bir şey için atalarının sorulmasına izin verir. Key_names kullanımı gerçekten işe yarıyor. – kevpie

+0

Bu harika, kevpie'nin önerdiği gibi Kullanıcıları Kullanıcıya bile yaptım. Bununla birlikte, birkaç sorunla uğraşmak zorunda kaldım: a) Her bir friend_id için bir Kullanıcı varlığı depolamıyorum, bu yüzden get_by_key_name kullanarak sorgularken aldığım Hiçbiri değerlerini filtrelemem gerekiyor; b) Diğer bazı alanlarla da işleri filtrelemem gerekiyor, ancak bunları DataStore'dan aldıktan sonra aldığım varlıklar üzerinde yapıyorum. Bunu yapmanın daha iyi bir yolu var mı? – abahgat

+0

Nick'in cevabında yayınlanan görüşmeleri mutlaka izleyin. Bir liste özelliği ile birlikte bir dizin öğesi kullanmak isteyebilirsiniz. Bu, Nick tarafından yayınlanan ilk konuşmada gösterilir. – kevpie

3

This Google I/O talk uğraştığın kesin durumu giderir. Bu yıl ayrıca his follow up talk'a da bakınız.

+0

Korkarım ki son konuşmada aynı bağlantıyı iki kez yayınladın. Buna atıf mı ediyordun? http://www.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html – abahgat

+0

Evet, öyleydim. Üzgünüm, düzeltildi. –