Paginare i dati con i cursori di query
Con i cursori delle query in Firestore, puoi suddividere i dati restituiti da una in batch, in base ai parametri da te definiti.
I cursori di query definiscono i punti di inizio e di fine di una query, consentendoti di:
- Restituisce un sottoinsieme dei dati.
- Impagina i risultati della query.
Tuttavia, per definire un intervallo specifico per una query, devi utilizzare il where()
metodo descritto in Query semplici.
Aggiungere un cursore semplice a una query
Utilizza i metodi startAt()
o startAfter()
per definire il punto di partenza per una query.
Il metodo startAt()
include il punto di partenza, mentre il metodo startAfter()
la esclude.
Ad esempio, se utilizzi startAt(A)
in una query, viene restituito l'intero alfabeto.
Se invece utilizzi startAfter(A)
, viene restituito B-Z
.
Versione web 9
import { query, orderBy, startAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), startAt(1000000));
Versione web 8
citiesRef.orderBy("population").startAt(1000000);
Swift
// Get all cities with population over one million, ordered by population. db.collection("cities") .order(by: "population") .start(at: [1000000])
Objective-C
// Get all cities with population over one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryStartingAtValues:@[ @1000000 ]];
Kotlin+KTX
Android
// Get all cities with a population >= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .startAt(1000000)
Java
Android
// 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]);
Java
Python
Python
(asincrono)
C++
// Get all cities with a population >= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .StartAt({FieldValue::Integer(1000000)});
Node.js
Vai
PHP
PHP
Per autenticarti a Firestore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Unity
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
C#
Ruby
Analogamente, utilizza i metodi endAt()
o endBefore()
per definire un punto di arrivo
per i risultati della query.
Versione web 9
import { query, orderBy, endAt } from "firebase/firestore"; const q = query(citiesRef, orderBy("population"), endAt(1000000));
Versione web 8
citiesRef.orderBy("population").endAt(1000000);
Swift
// Get all cities with population less than one million, ordered by population. db.collection("cities") .order(by: "population") .end(at: [1000000])
Objective-C
// Get all cities with population less than one million, ordered by population. [[[db collectionWithPath:@"cities"] queryOrderedByField:@"population"] queryEndingAtValues:@[ @1000000 ]];
Kotlin+KTX
Android
// Get all cities with a population <= 1,000,000, ordered by population, db.collection("cities") .orderBy("population") .endAt(1000000)
Java
Android
// 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]);
Java
Python
Python
(asincrono)
C++
// Get all cities with a population <= 1,000,000, ordered by population, db->Collection("cities") .OrderBy("population") .EndAt({FieldValue::Integer(1000000)});
Node.js
Vai
PHP
PHP
Per eseguire l'autenticazione su Firestore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Unity
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
C#
Ruby
Utilizzare uno snapshot del documento per definire il cursore della query
Puoi anche passare un'istantanea documento alla clausola cursore come inizio o fine del cursore di query. I valori nell'istantanea documento fungono da nel cursore di query.
Ad esempio, acquisisci uno snapshot di un documento "San Francisco" nel tuo set di dati di città e popolazioni. Poi, utilizza l'istantanea documento come punto di partenza. per cursore di query di compilazione. La query restituirà tutte le città con una popolazione maggiore o uguale a quella di San Francisco, come definita un'istantanea documento.
Versione web 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)); // ...
Versione web 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); // ... });
Swift
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) }
Objective-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
Android
// 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
Android
// 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") .startAtDocument(documentSnapshot); }, onError: (e) => print("Error: $e"), );
Java
Python
Python
(asincrono)
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
Vai
PHP
PHP
Per autenticarti a Firestore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, vedi Configura l'autenticazione per un ambiente di sviluppo locale.
Unity
CollectionReference citiesRef = db.Collection("cities"); DocumentReference docRef = citiesRef.Document("SF"); docRef.GetSnapshotAsync().ContinueWith((snapshotTask) => { Query query = citiesRef.OrderBy("Population").StartAt(snapshotTask.Result); });
C#
Ruby
Eseguire la paginazione di una query
Impagina le query combinando i cursori delle query con il metodo limit()
.
Ad esempio, utilizza l'ultimo documento di un batch come inizio di un cursore per il
batch successivo.
Versione web 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));
Versione web 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); });
Swift
// 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. // ... }
Objective-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
Android
// 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
Android
// 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") .startAfterDocument(lastVisible).limit(25); // Use the query for pagination // ... }, onError: (e) => print("Error completing: $e"), );
Java
Python
Python
(asincrono)
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
Vai
PHP
PHP
Per eseguire l'autenticazione su Firestore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Unity
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#
Ruby
Impostare il cursore in base a più campi
Quando utilizzi un cursore basato su un valore di campo (non un DocumentSnapshot), puoi precidere ulteriormente la posizione del cursore aggiungendo altri campi. Questo è particolarmente utile se il set di dati include più documenti che contengono lo stesso valore per il campo del cursore, rendendo la posizione del cursore ambigua. Puoi aggiungere altri valori di campo al cursore per specificare ulteriormente l'inizio o endpoint e ridurre l'ambiguità.
Ad esempio, in un set di dati contenente tutte le città denominate "Springfield" nel Stati Uniti, saranno presenti più punti di partenza per una query impostata su inizia da "Springfield":
Città | |
---|---|
Nome | Stato |
Springfield | Massachusetts |
Springfield | Missouri |
Springfield | Wisconsin |
Per iniziare da uno specifico Springfield, puoi aggiungere lo stato come secondario nella clausola del cursore.
Versione web 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"));
Versione web 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");
Swift
// 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"])
Objective-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
Android
// 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
Android
// 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"]);
Java
Python
Python
(asincrono)
C++
// This is not yet supported.
Node.js
Vai
PHP
PHP
Per eseguire l'autenticazione su Firestore, configura le credenziali predefinite dell'applicazione. Per ulteriori informazioni, consulta Configurare l'autenticazione per un ambiente di sviluppo locale.
Unity
Query query1 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield"); Query query2 = db.Collection("cities").OrderBy("Name").OrderBy("State").StartAt("Springfield", "Missouri");