2012-10-05 75 views
1

我在Google AppEngine上的應用程序出現問題,特別是在數據存儲區。 這個故事有點長。我的數據模型如下所示:appengine:如何通過密鑰在具有祖先的實體中查詢實體?

  1. 用戶可以創建實體。每個實體具有以下屬性: #1)。自動生成的密鑰。 #2)。創作者。 #3)。一個號碼。
  2. 在應用程序中,我正在做以下查詢: a)。按創建者查詢實體(#2)。 B)。通過數字屬性查詢實體(#3)。 C)。通過id查詢實體(#1)。

我正在使用低級數據存儲區API。現在,我已經嘗試了幾種有問題的方法:

[方法1]:對於數據存儲,如果我將實體設爲無父母(無祖先),那麼事情很好,特別是可以容易地實現查詢'c'由Datastore.get(k)。

方法1的問題:由於數據存儲「最終一致」,對於查詢「a」,結果總是不會更新至日期。如果用戶創建實體,然後列出他創建的所有實體,則新創建的實體總是缺失。它只會在幾秒鐘之後刷新...嘗試使用memcache,並沒有幫助(或者我找不到一個好方法?)。

爲了克服上述問題,我改變了數據結構。這裏是[方法2]:創建每個實體時,根據創建者創建一個密鑰,並將新實體作爲密鑰的子實體。因此,由用戶創建的所有實體都是具有祖先的實體。因此,查詢'a'適時地工作,並且查詢'b'似乎也工作。

Approach2的新問題:對於查詢'c',它總是不返回任何內容。這是我的查詢'c'。他們都找不到實體,總是:

方法1:
實體EN = datastore.get(K)

方法2:

DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); 
Query q = new Query(kind) 
    .setFilter(FilterOperator.EQUAL.of(Entity.KEY_RESERVED_PROPERTY, k)); 
Entity en = ds.prepare(q).asSingleEntity(); 

闖闖:Approach3: 集團所有一個祖先下的實體。這克服了Approach1中的問題,並且可以使用祖先過濾器進行查詢,因此可以檢索結果。

方法問題3:這樣的結構將所有實體分組爲一個實體組。根據Google數據存儲規範,寫入操作最多可發生5次。這是我不想打的限制...

我認爲這種數據模型非常普遍。有沒有合適的方法來構造數據?任何幫助表示讚賞。謝謝...

回答

1

我不太清楚你所問的,由於你的問題的格式,但...

當您通過ID你還必須包括父鍵查詢。密鑰包括父母和孩子的數據,如果你只使用孩子數據,那麼它不會返回你正在尋找的,因爲這不是「名稱」。完整路徑(祖先/孩子)是它的名字。

因此,請在您正在構建的密鑰中包含父項,然後獲取它。

key = parent, parent_ID, child, child_ID 

key = child, ID 

如果有父母,因爲關鍵是不完全行不通,也不能回到你想要這樣的數據。

+0

謝謝保羅的答案。與方法2一樣,實體被分組在不同的祖先之下,所以對於我想要查詢的所有實體沒有這種一對一的路徑。如果實體是在沒有祖先的情況下創建的,那麼查詢可以正常工作,但它始終不會更新(回到方法1)。 – Verilocos

+0

實際上還有另一種方法3:將所有實體分組在一個祖先中。它解決了方法1中的問題,可以像Paul提到的那樣查詢。但它存在一個新問題:按照Google數據存儲規範,一個祖先下的實體被視爲「一個實體組」,對「一個實體組」中的實體的寫操作存在限制:最多隻有5個每秒。這是另一個限制,我不想打到... – Verilocos

+0

關於最新的問題,我打算做什麼,當它成爲一個問題時,我明確寫入內容到memcache,然後嘗試並從中檢索它首先,如果失敗的話,只返回到數據存儲區。你說這對你不起作用,但我看不出爲什麼。如果你有一個返回數據的函數,但是它返回的數據是透明的(即它嘗試memcache,如果沒有則返回數據存儲),那麼就不能看出它不能爲你工作。一般來說,我會默認這樣做,因爲當我明確寫入新數據時,我總是可以使memcache無效。 –

相關問題