Com os cursores de consulta no Cloud Firestore, você pode dividir os dados retornados por uma consulta em lotes de acordo com os parâmetros definidos na consulta.
Os cursores de consulta definem os pontos inicial e final de uma consulta, permitindo:
- Retorne um subconjunto dos dados.
- Paginar os resultados da consulta.
Porém, para definir um intervalo específico para uma consulta, você deve usar o método where()
descrito em Consultas Simples .
Adicione um cursor simples a uma consulta
Use os métodos startAt()
ou startAfter()
para definir o ponto inicial de uma consulta. O método startAt()
inclui o ponto inicial, enquanto o método startAfter()
o exclui.
Por exemplo, se você usar startAt(A)
em uma consulta, ele retornará o alfabeto inteiro. Se você usar startAfter(A)
em vez disso, ele retornará BZ
.
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
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente Cloud Firestore .
Query query = citiesRef.OrderBy("Population").StartAt(1000000);
Da mesma forma, use os métodos endAt()
ou endBefore()
para definir um ponto final para os resultados da sua consulta.
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
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente Cloud Firestore .
Query query = citiesRef.OrderBy("Population").EndAt(1000000);
Use um instantâneo do documento para definir o cursor de consulta
Você também pode passar um instantâneo do documento para a cláusula cursor como o ponto inicial ou final do cursor de consulta. Os valores no instantâneo do documento servem como valores no cursor de consulta.
Por exemplo, tire um instantâneo de um documento “São Francisco” no seu conjunto de dados de cidades e populações. Em seguida, use esse instantâneo do documento como ponto de partida para o cursor de consulta de população. Sua consulta retornará todas as cidades com população maior ou igual à de São Francisco, conforme definido no instantâneo do documento.
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
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente Cloud Firestore .
CollectionReference citiesRef = db.Collection("cities");
DocumentReference docRef = citiesRef.Document("SF");
docRef.GetSnapshotAsync().ContinueWith((snapshotTask) =>
{
Query query = citiesRef.OrderBy("Population").StartAt(snapshotTask.Result);
});
Paginar uma consulta
Paginar consultas combinando cursores de consulta com o método limit()
. Por exemplo, use o último documento de um lote como início de um cursor para o próximo lote.
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
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente 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();
Defina o cursor com base em vários campos
Ao usar um cursor baseado em um valor de campo (não em um DocumentSnapshot), você pode tornar a posição do cursor mais precisa adicionando campos adicionais. Isso é particularmente útil se o seu conjunto de dados incluir vários documentos que tenham o mesmo valor para o campo do cursor, tornando a posição do cursor ambígua. Você pode adicionar valores de campo adicionais ao cursor para especificar melhor o ponto inicial ou final e reduzir a ambiguidade.
Por exemplo, em um conjunto de dados contendo todas as cidades denominadas "Springfield" nos Estados Unidos, haveria vários pontos iniciais para um conjunto de consultas começar em "Springfield":
Cidades | |
---|---|
Nome | Estado |
Springfield | Massachussets |
Springfield | Missouri |
Springfield | Wisconsin |
Para começar em um Springfield específico, você pode adicionar o estado como uma condição secundária na cláusula do cursor.
// 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
Para obter mais informações sobre como instalar e criar um cliente Cloud Firestore, consulte Bibliotecas de cliente 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");