借助 Cloud Firestore 中的查詢游標,您可以根據您在查詢中定義的參數將查詢返回的數據拆分為多個批次。
查詢游標定義查詢的起點和終點,允許您:
- 返回數據的一個子集。
- 分頁查詢結果。
但是,要為查詢定義特定範圍,您應該使用簡單查詢中描述的where()
方法。
向查詢添加一個簡單的游標
使用startAt()
或startAfter()
方法定義查詢的起點。 startAt()
方法包含起點,而startAfter()
方法不包含起點。
例如,如果您在查詢中使用startAt(A)
,它會返回整個字母表。如果您改用startAfter(A)
,它會返回BZ
。
Web version 9
import { query, orderBy, startAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), startAt(1000000));
Web version 8
citiesRef.orderBy("population").startAt(1000000);
迅速
// Get all cities with population over one million, ordered by population. db.collection("cities") .order(by: "population") .start(at: [1000000])
目標-C
// Get all cities with population over one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAtValues:@[ @1000000 ]];
Kotlin+KTX
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000)
Java
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000);
Dart
db.collection("cities").orderBy("population").startAt([1000000]);
爪哇
Python
Python
C++
// Get all cities with a population >= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .StartAt({FieldValue::Integer(1000000)});
節點.js
去
PHP
PHP
有關安裝和創建 Cloud Firestore 客戶端的更多信息,請參閱Cloud Firestore 客戶端庫。
統一
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
C#
紅寶石
同樣,使用endAt()
或endBefore()
方法定義查詢結果的終點。
Web version 9
import { query, orderBy, endAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), endAt(1000000));
Web version 8
citiesRef.orderBy("population").endAt(1000000);
迅速
// Get all cities with population less than one million, ordered by population. db.collection("cities") .order(by: "population") .end(at: [1000000])
目標-C
// Get all cities with population less than one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryEndingAtValues:@[ @1000000 ]];
Kotlin+KTX
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000)
Java
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000);
Dart
db.collection("cities").orderBy("population").endAt([1000000]);
爪哇
Python
Python
C++
// Get all cities with a population <= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .EndAt({FieldValue::Integer(1000000)});
節點.js
去
PHP
PHP
有關安裝和創建 Cloud Firestore 客戶端的更多信息,請參閱Cloud Firestore 客戶端庫。
統一
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
C#
紅寶石
使用文檔快照定義查詢游標
您還可以將文檔快照作為查詢游標的起點或終點傳遞給游標子句。文檔快照中的值用作查詢游標中的值。
例如,在您的城市和人口數據集中拍攝“舊金山”文檔的快照。然後,使用該文檔快照作為填充查詢游標的起點。您的查詢將返回人口大於或等於舊金山的所有城市,如文檔快照中所定義。
Web version 9
import { collection, doc, getDoc, query, orderBy, startAt } from "firebase/firestore"; const citiesRef = collection(db, "cities"); const docSnap = await getDoc(doc(citiesRef, "SF")); // Get all cities with a population bigger than San Francisco const biggerThanSf = query(citiesRef, orderBy("population"), startAt(docSnap)); // ...
Web version 8
var citiesRef = db.collection("cities"); return citiesRef.doc("SF").get().then((doc) => { // Get all cities with a population bigger than San Francisco var biggerThanSf = citiesRef .orderBy("population") .startAt(doc); // ... });
迅速
db.collection("cities") .document("SF") .addSnapshotListener { (document, error) in guard let document = document else { print("Error retreving cities: \(error.debugDescription)") return } // Get all cities with a population greater than or equal to San Francisco. let sfSizeOrBigger = db.collection("cities") .order(by: "population") .start(atDocument: document) }
目標-C
[[[db collectionWithPath:@"cities"] documentWithPath:@"SF"] addSnapshotListener:^(FIRDocumentSnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error retreiving cities: %@", error); return; } // Get all cities with a population greater than or equal to San Francisco. FIRQuery *sfSizeOrBigger = [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAtDocument:snapshot]; }];
Kotlin+KTX
// Get the data for "San Francisco" db.collection("cities").document("SF") .get() .addOnSuccessListener { documentSnapshot -> // Get all cities with a population bigger than San Francisco. val biggerThanSf = db.collection("cities") .orderBy("population") .startAt(documentSnapshot) // ... }
Java
// Get the data for "San Francisco" db.collection("cities").document("SF") .get() .addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() { @Override public void onSuccess(DocumentSnapshot documentSnapshot) { // Get all cities with a population bigger than San Francisco. Query biggerThanSf = db.collection("cities") .orderBy("population") .startAt(documentSnapshot); // ... } });
Dart
db.collection("cities").doc("SF").get().then( (documentSnapshot) { final biggerThanSf = db .collection("cities") .orderBy("population") .startAt([documentSnapshot]); }, onError: (e) => print("Error: $e"), );
爪哇
Python
Python
C++
db->Collection("cities").Document("SF").Get().OnCompletion( [db](const Future<DocumentSnapshot>& future) { if (future.error() == Error::kErrorOk) { const DocumentSnapshot& document_snapshot = *future.result(); Query bigger_than_sf = db->Collection("cities") .OrderBy("population") .StartAt({document_snapshot}); // ... } });
節點.js
去
PHP
PHP
有關安裝和創建 Cloud Firestore 客戶端的更多信息,請參閱Cloud Firestore 客戶端庫。
統一
CollectionReference citiesRef = db.Collection("cities"); DocumentReference docRef = citiesRef.Document("SF"); docRef.GetSnapshotAsync().ContinueWith((snapshotTask) => { Query query = citiesRef.OrderBy("Population").StartAt(snapshotTask.Result); });
C#
紅寶石
對查詢進行分頁
通過將查詢游標與limit()
方法組合來對查詢進行分頁。例如,使用批次中的最後一個文檔作為下一批次的游標的開始。
Web version 9
import { collection, query, orderBy, startAfter, limit, getDocs } from "firebase/firestore"; // Query the first page of docs const first = query(collection(db, "cities"), orderBy("population"), limit(25)); const documentSnapshots = await getDocs(first); // Get the last visible document const lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; console.log("last", lastVisible); // Construct a new query starting at this document, // get the next 25 cities. const next = query(collection(db, "cities"), orderBy("population"), startAfter(lastVisible), limit(25));
Web version 8
var first = db.collection("cities") .orderBy("population") .limit(25); return first.get().then((documentSnapshots) => { // Get the last visible document var lastVisible = documentSnapshots.docs[documentSnapshots.docs.length-1]; console.log("last", lastVisible); // Construct a new query starting at this document, // get the next 25 cities. var next = db.collection("cities") .orderBy("population") .startAfter(lastVisible) .limit(25); });
迅速
// Construct query for first 25 cities, ordered by population let first = db.collection("cities") .order(by: "population") .limit(to: 25) first.addSnapshotListener { (snapshot, error) in guard let snapshot = snapshot else { print("Error retreving cities: \(error.debugDescription)") return } guard let lastSnapshot = snapshot.documents.last else { // The collection is empty. return } // Construct a new query starting after this document, // retrieving the next 25 cities. let next = db.collection("cities") .order(by: "population") .start(afterDocument: lastSnapshot) // Use the query for pagination. // ... }
目標-C
FIRQuery *first = [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryLimitedTo:25]; [first addSnapshotListener:^(FIRQuerySnapshot *snapshot, NSError *error) { if (snapshot == nil) { NSLog(@"Error retreiving cities: %@", error); return; } if (snapshot.documents.count == 0) { return; } FIRDocumentSnapshot *lastSnapshot = snapshot.documents.lastObject; // Construct a new query starting after this document, // retreiving the next 25 cities. FIRQuery *next = [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAfterDocument:lastSnapshot]; // Use the query for pagination. // ... }];
Kotlin+KTX
// Construct query for first 25 cities, ordered by population val first = db.collection("cities") .orderBy("population") .limit(25) first.get() .addOnSuccessListener { documentSnapshots -> // ... // Get the last visible document val lastVisible = documentSnapshots.documents[documentSnapshots.size() - 1] // Construct a new query starting at this document, // get the next 25 cities. val next = db.collection("cities") .orderBy("population") .startAfter(lastVisible) .limit(25) // Use the query for pagination // ... }
Java
// Construct query for first 25 cities, ordered by population Query first = db.collection("cities") .orderBy("population") .limit(25); first.get() .addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() { @Override public void onSuccess(QuerySnapshot documentSnapshots) { // ... // Get the last visible document DocumentSnapshot lastVisible = documentSnapshots.getDocuments() .get(documentSnapshots.size() -1); // Construct a new query starting at this document, // get the next 25 cities. Query next = db.collection("cities") .orderBy("population") .startAfter(lastVisible) .limit(25); // Use the query for pagination // ... } });
Dart
// Construct query for first 25 cities, ordered by population final first = db.collection("cities").orderBy("population").limit(25); first.get().then( (documentSnapshots) { // Get the last visible document final lastVisible = documentSnapshots.docs[documentSnapshots.size - 1]; // Construct a new query starting at this document, // get the next 25 cities. final next = db .collection("cities") .orderBy("population") .startAfter([lastVisible]).limit(25); // Use the query for pagination // ... }, onError: (e) => print("Error completing: $e"), );
爪哇
Python
Python
C++
// Construct query for first 25 cities, ordered by population Query first = db->Collection("cities").OrderBy("population").Limit(25); first.Get().OnCompletion([db](const Future<QuerySnapshot>& future) { if (future.error() != Error::kErrorOk) { // Handle error... return; } // Get the last visible document const QuerySnapshot& document_snapshots = *future.result(); std::vector<DocumentSnapshot> documents = document_snapshots.documents(); const DocumentSnapshot& last_visible = documents.back(); // Construct a new query starting at this document, // get the next 25 cities. Query next = db->Collection("cities") .OrderBy("population") .StartAfter(last_visible) .Limit(25); // Use the query for pagination // ... });
節點.js
去
PHP
PHP
有關安裝和創建 Cloud Firestore 客戶端的更多信息,請參閱Cloud Firestore 客戶端庫。
統一
CollectionReference citiesRef = db.Collection("cities"); Query firstQuery = citiesRef.OrderBy("Population").Limit(3); // Get the last document from the results firstQuery.GetSnapshotAsync().ContinueWith((querySnapshotTask) => { long lastPopulation = 0; foreach (DocumentSnapshot documentSnapshot in querySnapshotTask.Result.Documents) { lastPopulation = documentSnapshot.GetValue<long>("Population"); } // Construct a new query starting at this document. // Note: this will not have the desired effect if multiple cities have the exact same population value Query secondQuery = citiesRef.OrderBy("Population").StartAfter(lastPopulation); Task<QuerySnapshot> secondQuerySnapshot = secondQuery.GetSnapshotAsync();
C#
紅寶石
基於多個字段設置游標
使用基於字段值(而非 DocumentSnapshot)的游標時,您可以通過添加額外的字段使光標位置更加精確。如果您的數據集包含多個文檔,這些文檔的游標字段都具有相同的值,從而使游標的位置不明確,這將特別有用。您可以向光標添加其他字段值以進一步指定起點或終點並減少歧義。
例如,在包含美國所有名為“Springfield”的城市的數據集中,查詢集將有多個起始點,從“Springfield”開始:
城市 | |
---|---|
姓名 | 狀態 |
斯普林菲爾德 | 馬薩諸塞州 |
斯普林菲爾德 | 密蘇里州 |
斯普林菲爾德 | 威斯康星州 |
要從特定的斯普林菲爾德開始,您可以將該州作為次要條件添加到游標子句中。
Web version 9
// Will return all Springfields import { collection, query, orderBy, startAt } from "firebase/firestore"; const q1 = query(collection(db, "cities"), orderBy("name"), orderBy("state"), startAt("Springfield")); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" const q2 = query(collection(db, "cities"), orderBy("name"), orderBy("state"), startAt("Springfield", "Missouri"));
Web version 8
// Will return all Springfields db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield"); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield", "Missouri");
迅速
// Will return all Springfields db.collection("cities") .order(by: "name") .order(by: "state") .start(at: ["Springfield"]) // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db.collection("cities") .order(by: "name") .order(by: "state") .start(at: ["Springfield", "Missouri"])
目標-C
// Will return all Springfields [[[[db collectionWithPath:@"cities"] queryOrderedByField:@"name"] queryOrderedByField:@"state"] queryStartingAtValues:@[ @"Springfield" ]]; // Will return "Springfield, Missouri" and "Springfield, Wisconsin" [[[[db collectionWithPath:@"cities"] queryOrderedByField:@"name"] queryOrderedByField:@"state"] queryStartingAtValues:@[ @"Springfield", @"Missouri" ]];
Kotlin+KTX
// Will return all Springfields db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield") // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield", "Missouri")
Java
// Will return all Springfields db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield"); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db.collection("cities") .orderBy("name") .orderBy("state") .startAt("Springfield", "Missouri");
Dart
// Will return all Springfields db .collection("cities") .orderBy("name") .orderBy("state") .startAt(["Springfield"]); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db .collection("cities") .orderBy("name") .orderBy("state") .startAt(["Springfield", "Missouri"]);
爪哇
Python
Python
C++
// This is not yet supported.
節點.js
去
PHP
PHP
有關安裝和創建 Cloud Firestore 客戶端的更多信息,請參閱Cloud Firestore 客戶端庫。
統一
Query query1 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield"); Query query2 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield", "Missouri");