總覽:在多個欄位使用範圍和不等式篩選器進行查詢

Cloud Firestore 支援在單一查詢中,對多個欄位使用範圍與不等式篩選器。您現在可以在多個欄位上設定範圍和不等式條件,並將篩選後邏輯的實作委派給 Cloud Firestore,以簡化應用程式的開發作業。

多個欄位的範圍和不相等篩選器

以下查詢會傳回年齡大於 35,且高度介於 60 到 70,並使用年齡和高度範圍篩選器的所有使用者。

網頁版 9 模組化

  const q = query(
      collection(db, "users"),
      where('age', '>', 35),
      where('height', '>', 60),
      where('height', '<', 70)
    );

Swift

 let query = db.collection("users")
   .whereField("age", isGreaterThan: 35)
   .whereField("height", isGreaterThan: 60)
   .whereField("height", isLessThan: 70)

Objective-C

 FIRQuery *query = 
  [[[[self.db collectionWithPath:@"users"]
 queryWhereField:@"age" isGreaterThan:@35]
    queryWhereField:@"height" isGreaterThan:@60] 
        queryWhereField:@"height" isLessThan:@70];

Java Android

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin+KTX Android

 val query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70)

Java

  db.collection("users")
    .whereGreaterThan("age", 35)
    .whereGreaterThan("height", 60)
    .whereLessThan("height", 70);

Node.js

db.collection("users")
  .where('age', '>', 35),
  .where('height', '>', 60),
  .where('height', '<', 70)

建立索引註意事項

在開始執行查詢之前,請務必詳閱查詢和 Cloud Firestore 資料模型

在 Cloud Firestore 中,查詢的 ORDER BY 子句會決定可用於提供查詢的索引。舉例來說,ORDER BY a ASC, b ASC 查詢需要針對 a ASC, b ASC 欄位提供複合式索引。

為提高 Cloud Firestore 查詢的效能與成本效益,請最佳化索引中的欄位順序。若要這麼做,應確保索引的排序方式是從左到右,以使查詢擷取至資料集,以防止掃描極端索引項目。

假設您要搜尋一群員工,並找到薪資超過 10,0000 人且工作年資大於 0 的員工。就您對資料集的瞭解,您知道薪酬限制比體驗限制更廣泛。如要減少索引掃描次數,理想索引會是 (salary [...], experience [...])。因此,需要快速且符合成本效益的查詢會在 experience 之前排序 salary,如下所示:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .whereGreaterThan("experience", 0)
  .orderBy("salary")
  .orderBy("experience");

Node.js

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .orderBy("salary")
  .orderBy("experience");

Python

db.collection("employees")
  .where("salary", ">", 100000)
  .where("experience", ">", 0)
  .order_by("salary")
  .order_by("experience");

最佳化索引的最佳做法

最佳化索引時,請注意下列最佳做法。

排序索引欄位的順序為等號,然後依序為選取範圍或不等式欄位

Cloud Firestore 會使用複合式索引最左側的欄位,在 orderBy() 查詢的第一個欄位中達到等式限制,以及範圍或不等式限制。這些限制可減少 Cloud Firestore 掃描的索引項目數量。Cloud Firestore 會使用索引的其餘欄位來滿足查詢的其他範圍或不等式限制。這些限制不會減少 Cloud Firestore 掃描的索引項目數量,但會篩除不相符的文件,減少傳回給用戶端的文件數量。

如要進一步瞭解如何建立高效率的索引,請參閱完美索引的定義

按照查詢限制選擇能力遞減排序欄位

為確保 Cloud Firestore 為您的查詢選取最佳索引,請指定 orderBy() 子句,該子句按照查詢限制選擇能力的遞減順序排序欄位。選擇程度越高,應與少數文件子集相符,而選取能力越低,即可與較小型的文件子集相符。請確認在索引排序中,選擇範圍較早的範圍或不等式欄位會比選取程度較低的欄位來得先。

為了盡量減少 Cloud Firestore 透過網路掃描及傳回的文件數量,請務必按照查詢限制選擇能力越低的順序將欄位排序。如果結果集不在必要順序中,且結果集預計會很小,您可以實作用戶端邏輯,依照您的訂購期望重新排序。

舉例來說,假設您想要搜尋一組員工,找出薪資超過 100000 的員工,然後按照員工經驗的年份排序結果。如果您預期只有少數員工的薪資超過 10, 0000 人,那麼編寫查詢的最有效率方法是如下:

Java

db.collection("employees")
  .whereGreaterThan("salary", 100000)
  .orderBy("salary")
  .get()
  .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
        @Override
        public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
          // Order results by `experience`
        }
    });;

Node.js

const querySnapshot = await db.collection('employees')
                              .where("salary", ">", 100000)
                              .orderBy("salary")
                              .get();

// Order results by `experience`

Python

results = db.collection("employees")
            .where("salary", ">", 100000)
            .order_by("salary")
            .stream()

// Order results by `experience`

雖然在 experience 上新增排序後,會產生相同的文件集並難以在用戶端重新排序結果,但查詢可能會讀取比先前的查詢更多多餘的索引項目。這是因為 Cloud Firestore 一律會優先選擇索引欄位前置字串與查詢子句相符的索引。如果按照子句將 experience 加入順序,Cloud Firestore 會選取 (experience [...], salary [...]) 索引來計算查詢結果。由於 experience 沒有其他限制,因此 Cloud Firestore 會先讀取 employees 集合的「所有」索引項目,然後再套用 salary 篩選器來尋找最終的結果集。這表示系統仍會讀取不符合 salary 篩選器的索引項目,導致查詢的延遲時間和成本增加。

定價

針對多個欄位套用範圍和不等式篩選器的查詢,將依據讀取的文件和讀取的索引項目計費。

詳情請參閱定價頁面。

限制

除了查詢限制之外,在針對多個欄位使用含有範圍與不等式篩選器的查詢之前,請注意下列限制:

  • 查詢不支援在文件欄位上使用範圍或不等式篩選器,且只對文件索引鍵 (__name__) 套用相等限制。
  • Cloud Firestore 將範圍或不等式欄位的數量限制為 10。以免查詢費用過高的執行。

後續步驟