查詢限制

本頁面涵蓋在 Google App Engine 查詢 Cloud Datastore 的相關限制。下方列出您在開發 Cloud Datastore 時會遇到的一般限制。

實體若缺少查詢中指定的屬性,就不會包含在查詢結果中

相同種類的實體不一定具備相同的屬性。針對每一個在查詢篩選器和排序順序中指定的屬性,實體都必須擁有一個值 (可能是空值),才有資格做為查詢結果。否則用於執行查詢的索引就會忽略該實體,查詢結果自然就不會包含該實體。

篩選未編入索引的屬性不會傳回任何結果

查詢找不到未編入索引的屬性值,也無法排序這類屬性。

不等式篩選器最多限用於一個屬性

為避免必須掃描整個索引,查詢機制會要求一個查詢的所有可能結果在索引中彼此相鄰。為符合這項限制,單項查詢只能將不等式比較運算 (<, <=, >, >=) 用於一個以上的屬性及其所有篩選器。例如,以下查詢的兩個不等式篩選器均適用於同一個屬性,因此查詢有效:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Filter("BirthYear <=", maxBirthYear)

但是,以下查詢「無效」,原因在於使用不等式篩選器查詢兩個不同的屬性:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Filter("Height <=", maxHeight) // ERROR

請注意,一項查詢「可以」搭配用來查詢不同屬性的等式 (=) 篩選器,以及一或多個用來查詢單一屬性的不等式篩選器。因此,以下「是」有效查詢:

q := datastore.NewQuery("Person").
	Filter("LastName =", targetLastName).
	Filter("City =", targetCity).
	Filter("BirthYear >=", minBirthYear).
	Filter("BirthYear <=", maxBirthYear)

若不指定排序順序,就不會定義查詢結果順序

如果查詢不指定排序順序,則會依擷取順序傳回結果。隨著 Cloud Datastore 實作的發展 (或是應用程式的索引變更時),這個順序可能會改變。因此,如果應用程式要求按照特定順序排列查詢結果,請務必在查詢中明確指定排序順序。

如果有等式篩選器,則屬性的排序順序將被忽略

如果查詢有特定屬性的等式篩選器,系統就會忽略針對這個屬性指定的任何排序順序。屬性的所有結果值均相同且不需進一步排序,這樣就不需要針對單值屬性進行多餘的處理,因此可輕鬆地達到最佳化。但如果是多值屬性,除了等式篩選器比對而得出的值之外,可能還包含其他值。由於這樣的使用情形並不多見,套用排序順序需耗費較多成本,而且需要建立其他索引,因此即使是多值屬性,Cloud Datastore 查詢規劃工具也會直接忽略排序順序。這可能會導致系統採用與排序順序不同的順序傳回查詢結果。

必須先排序不等式篩選器中使用的屬性

如要擷取所有與不等式篩選器相符的結果,查詢會掃描索引中符合篩選器的前兩列,接著再繼續掃描,直到發現不一致的列為止。連續列必須按照不等式篩選器中使用的屬性排序,排列在任何其他屬性之前,才能包含完整的結果集。因此,如果查詢指定一或多個不等式篩選器及一或多個排序順序,第一個排序順序必須參照不等式篩選器中具名的相同屬性。以下查詢有效:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("BirthYear").
	Order("LastName")

以下查詢「無效」,因為沒有按照不等式篩選器中所用的屬性排序:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("LastName") // ERROR

同理可證,以下查詢也無效,原因在於不等式篩選器所用的屬性並不是排序後的第一個屬性:

q := datastore.NewQuery("Person").
	Filter("BirthYear >=", minBirthYear).
	Order("LastName").
	Order("BirthYear") // ERROR

多值屬性有可能會出現令人意外的結果

由於實體建立索引的方式所致,如果實體的相同屬性具有多個值,有時候可能會與查詢篩選器及排序順序發生非預期的交互作用,因而出現令人意外的結果。

如果查詢有特定屬性的多個不等式篩選器,除非屬性至少有一個值符合「所有」篩選器的條件,否則實體無法與查詢相符。舉例來說,如果屬於 Widget 種類的實體包含 12 這兩個 x 屬性值,就「無法」與查詢相符:

q := datastore.NewQuery("Widget").
	Filter("x >", 1).
	Filter("x <", 2)

該實體的每一個 x 值均符合其中一個篩選器,但沒有一個值能同時符合兩個篩選器。請注意,等式篩選器不適用這項原則。舉例來說,以上實體就「會」符合以下查詢:

q := datastore.NewQuery("Widget").
	Filter("x =", 1).
	Filter("x =", 2)

即使該實體沒有任何一個 x 值同時符合兩種篩選情況也無妨。

多值屬性的排序順序也一樣不尋常。由於這類屬性會在每個不重複值的索引中出現一次,因此,索引中出現的第一個值決定實體的排序順序:

  • 如果按遞增順序排序查詢結果,排序時就會使用該屬性的最小值。
  • 如果按遞減順序排序結果,排序時就會使用最大值。
  • 其他值和值的數量都不會影響排序順序。

這種情況會出現不尋常的結果:按遞增順序「和」遞減順序排列時,含有 19 屬性值的實體都會排在含有 4567 屬性值的實體之前。

交易內部查詢必須包含祖系篩選器

Cloud Datastore 交易只能使用屬於同一個實體群組 (具備共同祖系) 的實體。為維護這項限制,在交易中執行的所有查詢都須包含一個祖系篩選器,且該篩選器會如同交易中的其他作業,在相同的實體群組中指定祖系。

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Go 適用的 App Engine 標準環境