Firestore (Datastore 模式) 支援在單一查詢中,對多個屬性使用範圍和不等式篩選器。這項功能可讓您對多個屬性設定範圍和不等式條件,並將後續篩選邏輯的實作作業委派給 Datastore 模式的 Firestore,簡化應用程式開發作業。
針對多個屬性使用範圍和不等式篩選條件
下列查詢會對優先順序和天數使用範圍篩選器,傳回優先順序大於 4 且完成期限少於 3 天的所有工作。
Go
query := datastore.NewQuery("Task").
FilterField("priority", ">", 4).
FilterField("days", "<", 3).
GQL
SELECT * FROM /tasks WHERE priority > 4 AND days < 3;
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("Task")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
.build();
Node.js
const query = datastore
.createQuery('Task')
.filter(
and([
new PropertyFilter('priority', '>', 4),
new PropertyFilter('days', '<', 3),
])
);
Python
from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))
PHP
$query = $datastore->query()
->kind('Task')
->filter('priority', '>', 4)
->filter('days', '<', 3)
C#
Query query = new Query("Task")
{
Filter = Filter.And(Filter.GreaterThan("priority", 4),
Filter.LessThan("days", 3))
};
Ruby
query = datastore.query("Task")
.where("priority", ">", 4)
.where("days", "<", 3)
建立索引的注意事項
開始執行查詢前,請務必先閱讀查詢相關資訊。
如果未指定 ORDER BY
子句,Firestore (Datastore 模式) 會使用任何可滿足查詢篩選條件的索引來提供查詢結果。這種做法會產生根據索引定義排序的結果集。
如要盡可能提高 Datastore 模式 Firestore 查詢的效能和成本效益,請最佳化索引中的屬性順序。如要達成這個目標,請確保索引從左到右排序,讓查詢精簡為資料集,避免掃描多餘的索引項目。
舉例來說,假設您想在員工集合中搜尋薪資超過 $100,000 美元,且年資超過 0 年的美國員工。根據您對資料集的瞭解,您知道薪資限制比經驗限制更具選擇性。可減少索引掃描次數的索引是 (salary [...], experience [...])
索引。因此,快速且具成本效益的查詢會先排序 salary
,再排序 experience
,如下例所示:
GQL
SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(
CompositeFilter.and(
PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
.setOrderBy(OrderBy("salary"), OrderBy("experience"))
.build();
Node.js
const query = datastore
.createQuery("employees")
.filter(
and([
new PropertyFilter("salary", ">", 100000),
new PropertyFilter("experience", ">", 0),
])
)
.order("salary")
.order("experience");
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]
最佳化索引的最佳做法
最佳化索引時,請注意下列最佳做法。
依等式排序查詢,然後依最具選擇性的範圍或不等式欄位排序
Firestore (Datastore 模式) 會使用複合索引最左側的屬性,來滿足 orderBy()
查詢第一個欄位的等式限制,以及範圍和不等式限制 (如有)。這些限制條件可減少 Firestore (Datastore 模式) 掃描的索引項目數量。Datastore 模式的 Firestore 會使用索引的其餘屬性,滿足查詢的其他範圍和不等式限制。這些限制不會減少 Firestore (Datastore 模式) 掃描的索引項目數量,但會篩除不相符的實體,減少傳回給用戶端的實體數量。
如要進一步瞭解如何建立有效率的索引,請參閱索引結構和定義,以及最佳化索引。
依查詢限制選擇性遞減順序排列屬性
為確保 Firestore (Datastore 模式) 為查詢選取最佳索引,請指定 orderBy()
子句,根據查詢中限制的選擇性,排序範圍和不相等屬性,從選擇性最高的屬性開始。選擇性越高,相符的實體就越少;選擇性越低,相符的實體就越多。在索引排序中,將選擇性較高的範圍和不等比較屬性,放在選擇性較低的屬性之前。
為盡量減少 Firestore (Datastore 模式) 掃描並透過網路傳回的實體數量,您應一律按照查詢限制選擇性的遞減順序排序屬性。如果結果集並非依所需順序排列,且結果集預計很小,您可以實作用戶端邏輯,按照預期順序重新排序。
舉例來說,假設您想在員工集合中搜尋薪資超過 $100,000 美元的美國員工,並依員工年資排序結果,如果您預期只有少數員工的薪資會超過 $100,000 美元,則可採用下列有效率的查詢撰寫方式:
Java
Query<Entity> query =
Query.newEntityQueryBuilder()
.setKind("employees")
.setFilter(PropertyFilter.gt("salary", 100000))
.setOrderBy(OrderBy("salary"))
.build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`
Node.js
const query = datastore
.createQuery("employees")
.filter(new PropertyFilter("salary", ">", 100000))
.order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`
Python
query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`
雖然在查詢中加入 experience
的排序條件會產生相同的實體集,並避免在用戶端重新排序結果,但查詢可能會讀取比先前查詢多出許多無關的索引項目。這是因為 Firestore (Datastore 模式) 一律會優先使用索引屬性前置字元與查詢的 order by 子句相符的索引。如果 experience
已新增至排序依據子句,則 Datastore 模式的 Firestore 會選取 (experience [...], salary [...])
索引,用於計算查詢結果。由於 experience
沒有其他限制,Firestore (Datastore 模式) 會先讀取 employees
集合的所有索引項目,再套用 salary
篩選器,找出最終結果集。也就是說,系統仍會讀取不符合 salary
篩選條件的索引項目,進而增加查詢的延遲時間和費用。
定價
如果查詢針對多個屬性使用範圍和不等式篩選條件,系統會根據讀取的實體和索引項目計費。
詳情請參閱定價頁面。
限制
除了查詢限制外,使用查詢時,如果範圍和不等式篩選條件套用至多個屬性,請注意下列限制:
- 為避免查詢作業耗費過多資源,Datastore 模式的 Firestore 將範圍或不等式運算子的數量限制為 10 個。
後續步驟
- 瞭解如何最佳化查詢。
- 進一步瞭解如何執行簡單和複合查詢。
- 瞭解 Firestore (Datastore 模式) 如何使用索引。