Con i cursori di query in Cloud Firestore, puoi dividere i dati restituiti da una query in batch in base ai parametri definiti nella query.
I cursori di query definiscono i punti di inizio e fine di una query, consentendo di:
- Restituisce un sottoinsieme di dati.
- Impagina i risultati della query.
Tuttavia, per definire un intervallo specifico per una query, dovresti utilizzare il metodo where()
descritto in Simple Query .
Aggiungi un semplice cursore a una query
Utilizzare i startAt()
o startAfter()
per definire il punto di inizio di una query. Il metodo startAt()
include il punto di inizio, mentre il metodo startAfter()
lo esclude.
Ad esempio, se si utilizza startAt(A)
in una query, restituisce l'intero alfabeto. Se invece usi startAfter(A)
, restituisce 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);
Veloce
// Get all cities with population over one million, ordered by population. db.collection("cities") .order(by: "population") .start(at: [1000000])
Obiettivo-C
// Get all cities with population over one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAtValues:@[ @1000000 ]];
Java
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000);
Kotlin+KTX
// 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]);
Giava
Pitone
Python
C++
// Get all cities with a population >= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .StartAt({FieldValue::Integer(1000000)});
Node.js
andare
PHP
$query = $citiesRef ->orderBy('population') ->startAt([1000000]);
Unità
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
C#
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
Rubino
Allo stesso modo, usa i endAt()
o endBefore()
per definire un punto finale per i risultati della query.
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);
Veloce
// Get all cities with population less than one million, ordered by population. db.collection("cities") .order(by: "population") .end(at: [1000000])
Obiettivo-C
// Get all cities with population less than one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryEndingAtValues:@[ @1000000 ]];
Java
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000);
Kotlin+KTX
// 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]);
Giava
Pitone
Python
C++
// Get all cities with a population <= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .EndAt({FieldValue::Integer(1000000)});
Node.js
andare
PHP
$query = $citiesRef ->orderBy('population') ->endAt([1000000]);
Unità
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
C#
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
Rubino
Utilizzare uno snapshot del documento per definire il cursore della query
Puoi anche passare uno snapshot del documento alla clausola cursor come punto iniziale o finale del cursore della query. I valori nello snapshot del documento fungono da valori nel cursore della query.
Ad esempio, scatta un'istantanea di un documento "San Francisco" nel tuo set di dati di città e popolazioni. Quindi, utilizza l'istantanea del documento come punto di partenza per il cursore della query di popolazione. La tua query restituirà tutte le città con una popolazione maggiore o uguale a quella di San Francisco, come definito nell'istantanea del documento.
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); // ... });
Veloce
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) }
Obiettivo-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]; }];
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); // ... } });
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) // ... }
Dart
db.collection("cities").doc("SF").get().then( (documentSnapshot) { final biggerThanSf = db .collection("cities") .orderBy("population") .startAt([documentSnapshot]); }, onError: (e) => print("Error: $e"), );
Giava
Pitone
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}); // ... } });
Node.js
andare
PHP
$citiesRef = $db->collection('samples/php/cities'); $docRef = $citiesRef->document('SF'); $snapshot = $docRef->snapshot(); $query = $citiesRef ->orderBy('population') ->startAt($snapshot);
Unità
CollectionReference citiesRef = db.Collection("cities"); DocumentReference docRef = citiesRef.Document("SF"); docRef.GetSnapshotAsync().ContinueWith((snapshotTask) => { Query query = citiesRef.OrderBy("Population").StartAt(snapshotTask.Result); });
C#
CollectionReference citiesRef = db.Collection("cities"); DocumentReference docRef = citiesRef.Document("SF"); DocumentSnapshot snapshot = await docRef.GetSnapshotAsync(); Query query = citiesRef.OrderBy("Population").StartAt(snapshot);
Rubino
Impagina una query
Impagina le query combinando i cursori di query con il metodo limit()
. Ad esempio, utilizzare l'ultimo documento in un batch come inizio di un cursore per il batch successivo.
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); });
Veloce
// 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. // ... }
Obiettivo-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. // ... }];
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 // ... } });
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 // ... }
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"), );
Giava
Pitone
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 // ... });
Node.js
andare
PHP
$citiesRef = $db->collection('samples/php/cities'); $firstQuery = $citiesRef->orderBy('population')->limit(3); # Get the last document from the results $documents = $firstQuery->documents(); $lastPopulation = 0; foreach ($documents as $document) { $lastPopulation = $document['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 $nextQuery = $citiesRef->orderBy('population')->startAfter([$lastPopulation]); $snapshot = $nextQuery->documents();
Unità
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#
CollectionReference citiesRef = db.Collection("cities"); Query firstQuery = citiesRef.OrderBy("Population").Limit(3); // Get the last document from the results QuerySnapshot querySnapshot = await firstQuery.GetSnapshotAsync(); long lastPopulation = 0; foreach (DocumentSnapshot documentSnapshot in querySnapshot.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); QuerySnapshot secondQuerySnapshot = await secondQuery.GetSnapshotAsync();
Rubino
Imposta il cursore in base a più campi
Quando si utilizza un cursore basato su un valore di campo (non un DocumentSnapshot), è possibile rendere più precisa la posizione del cursore aggiungendo campi aggiuntivi. Ciò è particolarmente utile se il set di dati include più documenti che hanno tutti lo stesso valore per il campo del cursore, rendendo ambigua la posizione del cursore. È possibile aggiungere valori di campo aggiuntivi al cursore per specificare ulteriormente il punto iniziale o finale e ridurre l'ambiguità.
Ad esempio, in un set di dati contenente tutte le città denominate "Springfield" negli Stati Uniti, ci sarebbero più punti di partenza per un set di query che inizi a "Springfield":
Città | |
---|---|
Nome | Stato |
Springfield | Massachusetts |
Springfield | Missouri |
Springfield | Wisconsin |
Per iniziare da uno Springfield specifico, puoi aggiungere lo stato come condizione secondaria nella clausola del cursore.
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");
Veloce
// 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"])
Obiettivo-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" ]];
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");
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")
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"]);
Giava
Pitone
Python
C++
// This is not yet supported.
Node.js
andare
PHP
// Will return all Springfields $query1 = $db ->collection('samples/php/cities') ->orderBy('name') ->orderBy('state') ->startAt(['Springfield']); // Will return "Springfield, Missouri" and "Springfield, Wisconsin" $query2 = $db ->collection('samples/php/cities') ->orderBy('name') ->orderBy('state') ->startAt(['Springfield', 'Missouri']);
Unità
Query query1 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield"); Query query2 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield", "Missouri");
C#
Query query1 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield"); Query query2 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield", "Missouri");