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

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

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

下列查詢使用範圍篩選器來查詢人口和密度,以找出所有 人口數超過 1,000,000 人和人口密度的城市 每單位面積不到 10,000 人。

網頁版 9 模組化

const q = query(
    collection(db, "cities"),
    where('population', '>', 1000000),
    where('density', '<', 10000),
  );

Swift

let query = db.collection("cities")
  .whereField("population", isGreaterThan: 1000000)
  .whereField("density", isLessThan: 10000)

Objective-C

FIRQuery *query =
 [[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
   queryWhereField:@"density" isLessThan:@10000];

Java Android

Query query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000);

Kotlin+KTX Android

val query = db.collection("cities")
 .whereGreaterThan("population", 1000000)
 .whereLessThan("density", 10000)

Go

   query := client.Collection("cities").
      Where("population", ">", 1000000).
      Where("density", "<", 10000)

Java

db.collection("cities")
  .whereGreaterThan("population", 1000000)
  .whereLessThan("density", 10000);

Node.js

db.collection("cities")
  .where('population', '>', 1000000),
  .where('density', '<', 10000)

Python

from google.cloud import firestore

db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)

PHP

$collection = $db->collection('samples/php/cities');
$chainedQuery = $collection
    ->where('population', '>', 1000000)
    ->where('density', '<', 10000);

C#

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef
    .WhereGreaterThan("Population", 1000000)
    .WhereLessThan("Density", 10000);
QuerySnapshot querySnapshot = await query.GetSnapshotAsync();
foreach (DocumentSnapshot documentSnapshot in querySnapshot)
{
    var name = documentSnapshot.GetValue<string>("Name");
    var population = documentSnapshot.GetValue<int>("Population");
    var density = documentSnapshot.GetValue<int>("Density");
    Console.WriteLine($"City '{name}' returned by query. Population={population}; Density={density}");
}

Ruby

query = cities_ref.where("population", ">", "1000000")
                  .where("density", "<", 10000)

C++

CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
                       .WhereLessThan("density", FieldValue::Integer(10000));

Unity

CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
                      .WhereLessThan("density", 10000);

Dart

final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
                  .where("density", isLessThan: 10000);

建立索引註意事項

執行查詢前,請先閱讀 關於查詢和 Cloud Firestore 資料模型

在 Cloud Firestore 中,查詢的 ORDER BY 子句會決定哪些索引 以便提供查詢例如,執行 ORDER BY a ASC, b ASC 查詢 需要 a ASC, b ASC 欄位的複合式索引。

如要最佳化 Cloud Firestore 查詢的效能與成本效益, 最佳化索引中的欄位順序。如要執行此操作 並由左至右排序查詢,以擷取至資料集 防止掃描不必要的索引項目。

假設您想搜尋一群員工並找到美國 薪資超過 $100,000 美元的員工,而且工作年資相當於 大於 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 掃描及傳回的文件數量 網路,您應一律按照查詢順序由低至高排序欄位 限制選擇能力如果結果集不是必要順序,而且 結果集應該很小,您可以實作用戶端邏輯 重新下單。

舉例來說,假設您想搜尋一群員工 薪資超過 $100,000 美元的美國員工,按照年度 員工的經驗。如果您預期只有少數員工會獲得薪資 ,那麼寫入查詢最有效率的方式如下:

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。這是為了避免查詢費用過高 執行。

後續步驟