5

Powiedzmy mam to naprawdę proste rodzic/dziecko relatiosnship (dowolny Answer instancje klasy zawsze ma Question rodzica):Google NDB: Najlepszy sposób odczytywania encji podrzędnych z obiektu, powtarzanych właściwości w porównaniu do zwykłych zapytań?

class Answer(ndb.Model): 
    content = ndb.StringProperty() 
    timestamp = ndb.DateTimeProperty() 

    def to_message(): 
     """Returns a protoRPC message object of the answer""" 


class Question(ndb.Model): 
    content = ndb.StringProperty() 
    answers = ndb.KeyProperty(repeated = True, kind = 'Answer') 

    def to_message(self): 
     """Returns a protoRPC message object of the question""" 

Dwa to message metody są po prostu wykorzystywane do powrotu obiektu protoRPC. Pytanie brzmi: w moim sposobie to_message w klasie Question, jeśli chcę, aby pobrać wszystkie dzieci Answer instancji, pobierać je i wykorzystywać własną metodę to_message aby je w ładnym rpc Wiadomość jest lepiej:

  • iteracyjne nad anwers powtórzone listy KeyProperty
  • Wykonaj zapytanie przy użyciu filtra na „macierzystej” własności i iteracyjne nad listy wyprowadza

Pod względem dostępu NDB, pierwsza metoda wydaje być najlepszym, ale ponieważ i tak przekroczymy wolny limit, zastanawiam się, czy magazyn danych nie jest bardziej wydajny w pobieraniu rzeczy niż ja, iterując po tej liście.

Edytuj: Pierwotne pytanie ma bardzo prostą i oczywistą odpowiedź: pierwszy sposób. Prawdziwe pytanie byłoby, na wypadek, gdyby musiałem odfiltrować niektóre jednostki Answer na podstawie ich atrybutów (na przykład timestamp): czy lepiej jest wyszukiwać za pomocą filtru, czy iterować po liście i używać warunku do zbierania tylko " ciekawe "byty?

Odpowiedz

4

Z tego schematu nie masz nic do kwerendy, ponieważ masz już klucze każdej odpowiedzi jako lista kluczy w question_entity.answers

Więc trzeba tylko przynieść odpowiedź, że za pomocą klawiszy. Jest lepszy, jeśli uzyskasz wszystkie odpowiedzi tylko w jednej operacji.

list_of_answers = ndb.get_multi(question_entity.answers) 

(Więcej informacji na NDB Entities and Keys)

Z drugiej strony, jeśli model, który związek z KeyProperty w Answer:

class Answer(ndb.Model): 
    question = ndb.KeyProperty(Question) 
    content = ndb.StringProperty() 
    timestamp = ndb.DateTimeProperty() 

def to_message(): 
    """Returns a protoRPC message object of the answer""" 

lub przodków:

answer = Answer(parent=question_entity.key) 

W tych przypadkach należy użyć normalnego zapytania dla pobierać odpowiedź:

answers = Answer.query(Answer.question == question_entity.key) 

lub zapytanie przodka:

answers = Answer.query(ancestor = question_entity.key) 

odpowiednio.

Oznacza to dwa zadania: zapytaj o indeks oraz, pobierając datastore. Podsumowując, w tym przypadku pierwsze podejście jest tańsze w przypadku pobierania danych z magazynów.

+0

Dzięki za odpowiedź ... Myślę, że moje obecne pytanie jest trochę głupie. Prawdziwe pytanie brzmi: wyobraź sobie, że mam listę kluczy i chcę uzyskać listę jednostek odfiltrowanych przez pewien warunek na jednym z ich atrybutów (na przykład wartość znacznika czasowego). Czy bardziej wydajne jest zapytanie lub powtórzenie listy? – hadware

+0

W takim przypadku ze swoim schematem nie można wykonać zapytania. Powinieneś iterować po wszystkich encji i filtrować za pomocą kodu Pythona. Inną opcją jest użycie 'KeyProperty (Question)' w 'Answer' jak w powyższym przykładzie. W takim przypadku możesz filtrować odpowiedzi według pytania, a także inne atrybuty w tym samym zapytaniu. Ostatnia opcja jest tańsza (i szybsza), ponieważ pobierasz tylko odpowiedzi, których potrzebujesz. –

+0

Trzecia (lub czwarta, jeśli zlicza się przodków) opcja używa [Structured Property] (https://developers.google.com/appengine/docs/python/ndb/properties#structured). Jak wszystko ma plusy i minusy. –

2

Używanie na liście kluczy do pobrania odpowiedzi, a następnie iterowanie w celu wywołania ich metod to_message będzie najbardziej wydajne.

+0

Czy można udzielić bardziej szczegółowych informacji na temat skuteczności swojej metody? – hadware