בעזרת הסמן של השאילתה ב-Cloud Firestore, אפשר לפצל נתונים שמוחזרים על ידי שאילתה למקבצים בהתאם לפרמטרים שמגדירים בשאילתה.
הסמן של השאילתה מגדיר את נקודות ההתחלה והסיום של השאילתה, ומאפשר לכם:
- החזרת קבוצת משנה של הנתונים.
- עימוד תוצאות השאילתה.
עם זאת, כדי להגדיר טווח ספציפי לשאילתה, צריך להשתמש בשיטה where()
שמתוארת בקטע שאילתות פשוטות.
הוספת סמן פשוט לשאילתה
משתמשים ב-method startAt()
או ב-method startAfter()
כדי להגדיר את נקודת ההתחלה של שאילתה.
השיטה startAt()
כוללת את נקודת ההתחלה, בעוד שהשיטה startAfter()
לא כוללת אותה.
לדוגמה, אם משתמשים ב-startAt(A)
בשאילתה, המערכת מחזירה את כל האלפבית.
אם משתמשים ב-startAfter(A)
במקום זאת, הפונקציה מחזירה את הערך B-Z
.
import { query, orderBy, startAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), startAt(1000000));
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])
// Get all cities with population over one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAtValues:@[ @1000000 ]];
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000)
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000);
db.collection("cities").orderBy("population").startAt([1000000]);
// Get all cities with a population >= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .StartAt({FieldValue::Integer(1000000)});
PHP
מידע נוסף על התקנה ויצירה של לקוח Cloud Firestore זמין במאמר ספריות לקוח של Cloud Firestore.
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
באופן דומה, משתמשים בשיטות endAt()
או endBefore()
כדי להגדיר נקודת סיום לתוצאות השאילתה.
import { query, orderBy, endAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), endAt(1000000));
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])
// Get all cities with population less than one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryEndingAtValues:@[ @1000000 ]];
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000)
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000);
db.collection("cities").orderBy("population").endAt([1000000]);
// Get all cities with a population <= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .EndAt({FieldValue::Integer(1000000)});
PHP
מידע נוסף על התקנה ויצירה של לקוח Cloud Firestore זמין במאמר ספריות לקוח של Cloud Firestore.
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
שימוש בתמונת מצב של מסמך כדי להגדיר את הסמן של השאילתה
אפשר גם להעביר תמונת מצב של מסמך לפסקת הסמן בתור נקודת ההתחלה או נקודת הסיום של הסמן של השאילתה. הערכים בתמונת המצב של המסמך משמשים כערכים בסמן השאילתה.
לדוגמה, אפשר לצלם קובץ snapshot של המסמך 'תל אביב' במערך הנתונים של ערים ואוכלוסיות. לאחר מכן משתמשים בתמונת המצב של המסמך כנקודת ההתחלה של הסמן של שאילתת האוכלוסייה. השאילתה תחזיר את כל הערים עם אוכלוסייה גדולה מזו של סן פרנסיסקו או שווה לה, כפי שהוגדר בתמונת המצב של המסמך.
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)); // ...
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) }
[[[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]; }];
// 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) // ... }
// 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); // ... } });
db.collection("cities").doc("SF").get().then( (documentSnapshot) { final biggerThanSf = db .collection("cities") .orderBy("population") .startAtDocument(documentSnapshot); }, onError: (e) => print("Error: $e"), );
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}); // ... } });
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); });
חלוקה לדפים של שאילתה
כדי לפצל שאילתות לדפים, משלבים בין סמני שאילתות לבין השיטה limit()
.
לדוגמה, אפשר להשתמש במסמך האחרון בקבוצה כתחילת הסמן של הקבוצה הבאה.
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));
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. // ... }
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. // ... }];
// 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 // ... }
// 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 // ... } });
// 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") .startAfterDocument(lastVisible) .limit(25); // Use the query for pagination // ... }, onError: (e) => print("Error completing: $e"), );
// 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 // ... });
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();
הגדרת הסמן על סמך כמה שדות
כשמשתמשים בסמן שמבוסס על ערך שדה (ולא על DocumentSnapshot), אפשר להוסיף שדות נוספים כדי למקם את הסמן בצורה מדויקת יותר. האפשרות הזו שימושית במיוחד אם קבוצת הנתונים כוללת כמה מסמכים עם אותו ערך בשדה הסמן, וכתוצאה מכך המיקום של הסמן לא ברור. אפשר להוסיף ערכי שדות נוספים לסמן כדי לציין בצורה מדויקת יותר את נקודת ההתחלה או הסיום, וכדי לצמצם את הבלבול.
לדוגמה, בקבוצת נתונים שמכילה את כל הערים שנקראות 'Springfield' בארצות הברית, יהיו כמה נקודות התחלה לשאילתה שמוגדרת להתחיל ב-'Springfield':
ערים | |
---|---|
שם | מדינה |
Springfield | מסצ'וסטס |
Springfield | מיסורי |
Springfield | וויסקונסין |
כדי להתחיל ב-Springfield ספציפית, אפשר להוסיף את המדינה כתנאי משני בפסקת הסמן.
// 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"));
// 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"])
// 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" ]];
// 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") .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") .orderBy("name") .orderBy("state") .startAt(["Springfield"]); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" db .collection("cities") .orderBy("name") .orderBy("state") .startAt(["Springfield", "Missouri"]);
// This is not yet supported.
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");