2013-05-30 74 views
1

我有這樣的結構:有章(祖先=書)有網頁圖書(祖先=章)在NDB使用鍵檢索實體

顯然對我來說,要搜索由章ID,我需要通過祖先查詢來搜索這本書。我已經學會今天,如果我把所有的鑰匙,我可以直接檢索,而不需要先拿到這本書,那麼章,然後在頁面的實體,以這樣的方式

page_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId), 'Page', long(pageId)) 
page = page_key.get() 

我的疑問是:通過例如頁碼獲取頁面,我必須首先閱讀該章節嗎?

例如:

class Book(ndb.Model): 
    name = ndb.StringProperty(required=True) 

    # Search by id 
    @classmethod 
    def by_id(cls, id): 
     return Book.get_by_id(long(id)) 

class Chapter(ndb.Model): 
    name = ndb.StringProperty(required=True) 

    # Search by id 
    @classmethod 
    def by_id(cls, id, book): 
     return Chapter.get_by_id(long(id), parent=book.key) 

class Page(ndb.Model): 
    pageNumber = ndb.IntegerProperty(default=1) 
    content = ndb.StringProperty(required=True) 

    # Search by page 
    @classmethod 
    def by_page(cls, number, chapter): 
     page = Page.query(ancestor=chapter.key) 
     page = page.filter(Page.pageNumber == int(number)) 
     return page.get() 

事實上,當我需要搜索頁面來顯示其內容,我這樣做:

GETPAGE BOOKID = 5901353784180736 & chapterId = 5655612935372800 &頁= 2

所以,在控制器中,我有這樣的:

def get(self): 
    # Get the id parameters 
    bookId = self.request.get('bookId') 
    chapterId = self.request.get('chapterId') 
    pageNumber = self.request.get('page') 

    if bookId and chapterId and pageNumber: 
     # Must be a digit 
     if bookId.isdigit() and chapterId.isdigit() and pageNumber.isdigit(): 
      # Get the chapter 
      chapter_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId)) 
      chapter = chapter_key.get() 

      if chapter: 
       # Get the page 
       page = Page.by_number(pageNumber, chapter) 

這是正確的方式還是有更好的方式我錯過了我只能訪問數據存儲的地方,而不是兩個?

如果這是正確的,我想這種使用NDB的工作方式不會對數據存儲產生任何影響,因爲對這個頁面的重複調用總是碰到相同章節和頁面的NDB緩存(因爲我' m使用get()方法,它不是fetch()命令)。我的想法是對的嗎?

+0

可能重複(http://stackoverflow.com/questions/16830697 /與祖先在一起工作) –

+0

你爲什麼再問這個問題? –

+0

不一樣@DanielRoseman。在上一個問題中,您解決了有鑰匙讀取3次的問題。現在這個問題是要知道是否有其他方式讓實體不知道密鑰。對不起,如果我困惑你。 – Eagle

回答

2

您可以通過做一個祖先查詢一次性做到這一點,而不是一個GET:在GAE與祖先工作]的

chapter_key = ndb.Key('Book', long(bookId), 'Chapter', long(chapterId)) 
page = Page.query(Page.pageNumber==pageNumber, ancestor=chapter_key) 
+0

偉大的人!,它完美的作品。我對祖先的關鍵有點誤解,但我現在認爲我更瞭解它。在我的** by_page **方法中,我傳遞章節實體,但是通過_ancestor = chapter.key_進行搜索,這是愚蠢的,因爲我只需要密鑰。我將改變我所有的代碼,只使用鍵而不使用完整的實體,只需要鍵,這將爲我節省大量的數據庫命中。 – Eagle

+0

關於最後一個問題,我說得對嗎?即使調用3個不同的實體,因爲我正在使用get(),NDB正在從緩存中獲取它們,從而將命中最小化到數據庫? – Eagle

+1

在某種程度上,是的,但是您不能保證事情確實存在於緩存中,所以最好儘可能減少數據存儲訪問。 –