本頁面涵蓋在 Google App Engine 查詢 Datastore 的相關限制。下方列出您在針對 Datastore 進行開發時會遇到的一般限制。
系統會忽略查詢中缺少屬性名稱的實體
相同種類的實體不一定具備相同的屬性。針對每一個在查詢篩選器和排序順序中指定的屬性,實體都必須擁有一個值 (可能是空值),才有資格做為查詢結果。否則用於執行查詢的索引就會忽略該實體,查詢結果自然就不會包含該實體。
篩選未建立索引的屬性不會傳回任何結果
查詢找不到未建立索引的屬性值,也無法排序這類屬性。請參閱資料儲存庫索引頁面,瞭解未建立索引的屬性相關詳細說明。
不等式篩選器最多限用於一個屬性
為避免必須掃描整個索引,查詢機制會要求一個查詢的所有可能結果在索引中彼此相鄰。為符合這項限制,單一查詢不能將不等式比較運算 (<
、<=
、>
、>=
、!=
) 用於所有篩選器中超過一個屬性。例如,以下查詢的兩個不等式篩選器會套用至相同屬性,因此查詢有效:
SELECT * FROM Person WHERE birth_year >= :min_birth_year
AND birth_year <= :max_birth_year
但是,以下查詢「無效」,原因在於其對兩個不同的屬性使用不等式篩選器:
SELECT * FROM Person WHERE birth_year >= :max_birth_year
AND height <= :max_height # ERROR
請注意,一項查詢「可以」結合用於查詢不同屬性的等式 (=
) 篩選器,以及用於查詢單一屬性的一或多個不等式篩選器。因此,以下「是」有效查詢:
若不指定排序順序,就不會定義查詢結果順序
查詢若不指定排序順序,會依擷取順序傳回結果。隨著 Datastore 實作的發展 (或是應用程式的索引變更時),這個順序可能會改變。因此,若您的應用程式要求按照特定順序排列查詢結果,請務必在查詢中清楚指定該排序順序。
如果有等式篩選器,則屬性的排序順序將被忽略
如果查詢有特定屬性的等式篩選器,系統就會忽略針對這個屬性指定的任何排序順序。因為屬性的所有結果值均相同且不需進一步排序,在不需要針對單值屬性進行多餘處理的狀況下,可以輕鬆地達到最佳化。但如果是多值屬性,除了比對等式篩選條件得出的值之外,可能還包含其他值。由於這樣的使用情形並不多見,套用排序順序需耗費較多成本,而且需要建立其他索引,因此即使是多值屬性,Datastore 查詢規劃工具也會直接忽略排序順序。這可能會導致查詢結果以異於排序隱含的順序傳回。
必須先排序不等式篩選器中使用的屬性
如要擷取所有與不等式篩選器相符的結果,查詢會掃描索引中符合篩選器的第一列,接著再繼續掃描,直到發現不一致的列為止。連續列必須按照不等式篩選器中使用的屬性排序,排列在任何其他屬性之前,才能包含完整的結果集。因此,如果查詢指定一或多個不等式篩選器及一或多個排序順序,第一個排序順序必須參照不等式篩選器中具名的相同屬性。以下查詢有效:
SELECT * FROM Person WHERE birth_year >= :min_birth_year ORDER BY birth_year, last_name以下查詢「無效」,因為沒有按照不等式篩選器中所用的屬性排序:
SELECT * FROM Person WHERE birth_year >= :min_birth_year ORDER BY last_name # ERROR同理可證,以下查詢也無效,原因在於不等式篩選器所用的屬性並不是排序後的第一個屬性:
SELECT * FROM Person WHERE birth_year >= :min_birth_year
ORDER BY last_name, birth_year # ERROR
多值屬性有可能會出現令人意外的結果
由於實體建立索引的方式所致,如果實體的相同屬性具有多個值,有時候可能會與查詢篩選器及排序順序發生非預期的交互作用,因而出現令人意外的結果。
若查詢包含指定屬性的多個不等式篩選條件,除非屬性至少有一個屬性值符合「所有」篩選條件,否則實體不會與查詢一致。舉例來說,如果屬於 Widget
種類的實體包含 1
和 2
這兩個 x
屬性值,就「無法」與查詢相符:
SELECT * FROM Widget WHERE x > 1
AND x < 2
每個實體的 x
值各自符合其中一個篩選條件,但沒有一個值同時符合兩個篩選條件。請注意,等式篩選條件不適用這項原則。舉例來說,以上實體就「會」符合以下查詢條件:
SELECT * FROM Widget WHERE x = 1
AND x = 2
即使實體沒有任何一個 x
值同時符合兩種篩選條件也無妨。
不等於 (!=
) 運算子的用途在於進行「值不是」測試。舉例來說,以下查詢
SELECT * FROM Widget WHERE x != 1
符合 x
值不是 1
的任何 Widget
實體。
多值屬性的排序順序也一樣不尋常。由於這類屬性會在每個不重複值的索引中出現一次,因此,索引中出現的第一個值決定實體的排序順序:
- 如果按遞增順序排序查詢結果,排序時就會使用該屬性的最小值。
- 如果按遞減順序排序結果,排序時就會使用最大值。
- 其他值和值的數量都不會影響排序順序。
這種情況會出現不尋常的結果:按遞增順序「和」遞減順序排列時,含有 1
和 9
屬性值的實體都會排在含有 4
、5
、6
和 7
屬性值的實體之前。
交易內部查詢必須包含祖系篩選器
Datastore 交易只能使用屬於同一個實體群組 (具備共同祖系) 的實體。為維護這項限制,在交易中執行的所有查詢都須包含一個祖系篩選器,且該篩選器會如同交易中的其他作業,在相同的實體群組中指定祖系。