Panoramica delle query con filtri di intervallo e di disuguaglianza su più campi
Firestore supporta l'utilizzo di filtri di intervallo e disuguaglianza su più campi in una singola query. Puoi avere condizioni di intervallo e disuguaglianza su più campi e semplificare lo sviluppo delle applicazioni delegando l'implementazione della logica di post-filtraggio a Firestore.
Filtri per intervallo e disuguaglianza su più campi
La seguente query utilizza filtri di intervallo su popolazione e densità per restituire tutte le città in cui la popolazione è superiore a 1.000.000 di persone e la densità di popolazione è inferiore a 10.000 persone per unità di superficie.
Versione web 9 modulare
const q = query(
collection(db, "cities"),
where('population', '>', 1000000),
where('density', '<', 10000),
);
Swift
let query = db.collection("cities")
.whereField("population", isGreaterThan: 1000000)
.whereField("density", isLessThan: 10000)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"cities"]
queryWhereField:@"population" isGreaterThan:@1000000]
queryWhereField:@"density" isLessThan:@10000];
Java Android
Query query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Kotlin+KTX Android
val query = db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000)
Vai
query := client.Collection("cities").
Where("population", ">", 1000000).
Where("density", "<", 10000)
Java
db.collection("cities")
.whereGreaterThan("population", 1000000)
.whereLessThan("density", 10000);
Node.js
db.collection("cities")
.where('population', '>', 1000000),
.where('density', '<', 10000)
Python
from google.cloud import firestore
db = firestore.Client()
query = db.collection("cities")
.where("population", ">", 1000000)
.where("density", "<", 10000)
PHP
C#
Ruby
query = cities_ref.where("population", ">", "1000000")
.where("density", "<", 10000)
C++
CollectionReference cities_ref = db->Collection("cities");
Query query = cities_ref.WhereGreaterThan("population", FieldValue::Integer(1000000))
.WhereLessThan("density", FieldValue::Integer(10000));
Unity
CollectionReference citiesRef = db.Collection("cities");
Query query = citiesRef.WhereGreaterThan("population", 1000000)
.WhereLessThan("density", 10000);
Dart
final citiesRef = FirebaseFirestore.instance.collection('cities')
final query = citiesRef.where("population", isGreaterThan: 1000000)
.where("density", isLessThan: 10000);
Considerazioni sull'indicizzazione
Prima di eseguire le query, leggi informazioni sulle query e sul modello di dati di Firestore.
In Firestore, la clausola ORDER BY
di una query determina quali indici
possono essere utilizzati per pubblicare la query. Ad esempio, una query ORDER BY a ASC, b ASC
richiede un indice composto sui campi a ASC, b ASC
.
Per ottimizzare le prestazioni e il costo delle query Firestore, ottimizza l'ordine dei campi nell'indice. A questo scopo, assicurati che l'indice sia ordinato da sinistra a destra in modo che la query venga distillata in un set di dati che impedisce la scansione di voci di indice non necessarie.
Supponiamo che tu voglia cercare in una raccolta di dipendenti e trovare i dipendenti
degli Stati Uniti il cui stipendio è superiore a 100.000 $e il cui numero di anni di esperienza è
maggiore di 0. In base alla tua comprensione del set di dati, sai che il
vincolo salariale è più selettivo del vincolo di esperienza. L'indice ideale che ridurrebbe il numero di scansioni dell'indice sarebbe (salary [...], experience [...])
. Pertanto, la query rapida ed
economica ordinerà salary
prima di experience
e avrà il seguente aspetto:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.whereGreaterThan("experience", 0)
.orderBy("salary")
.orderBy("experience");
Node.js
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.orderBy("salary")
.orderBy("experience");
Python
db.collection("employees")
.where("salary", ">", 100000)
.where("experience", ">", 0)
.order_by("salary")
.order_by("experience");
Best practice per l'ottimizzazione degli indici
Quando ottimizzi gli indici, tieni presente le seguenti best practice.
Ordina i campi indice in base alle uguaglianze, seguite dal campo di intervallo o disuguaglianza più selettivo
Firestore utilizza i campi più a sinistra di un indice composto per soddisfare i vincoli di uguaglianza e il vincolo di intervallo o disuguaglianza, se presente, sul primo campo della query orderBy()
. Questi vincoli possono ridurre il numero di voci di indice analizzate da Firestore. Firestore utilizza i campi rimanenti
dell'indice per soddisfare altri vincoli di intervallo o disuguaglianza della query. Questi vincoli non riducono il numero di voci di indice analizzate da Firestore, ma filtrano i documenti non corrispondenti in modo che il numero di documenti restituiti ai client sia ridotto.
Per saperne di più sulla creazione di indici efficienti, consulta Proprietà dell'indice.
Ordina i campi in ordine decrescente di selettività del vincolo di query
Per assicurarti che Firestore selezioni l'indice ottimale per la tua query,
specifica una clausola orderBy()
che ordina i campi in ordine decrescente di selettività del vincolo della query. Una selettività più elevata corrisponde a un sottoinsieme più piccolo di documenti, mentre una selettività più bassa corrisponde a un sottoinsieme più grande di documenti. Assicurati di selezionare i campi di intervallo o di disuguaglianza con selettività più elevata all'inizio dell'ordinamento dell'indice rispetto ai campi con selettività inferiore.
Per ridurre al minimo il numero di documenti che Firestore scansiona e restituisce sulla rete, devi sempre ordinare i campi in ordine decrescente di selettività del vincolo della query. Se il set di risultati non è nell'ordine richiesto e si prevede che sia piccolo, puoi implementare la logica lato client per riordinarlo in base alle tue aspettative di ordinamento.
Ad esempio, supponiamo che tu voglia cercare in una raccolta di dipendenti per trovare i dipendenti degli Stati Uniti il cui stipendio è superiore a 100.000 $e ordinare i risultati in base all'anno di esperienza del dipendente. Se prevedi che solo un numero ridotto di dipendenti avrà stipendi superiori a 100.000 $, il modo più efficiente per scrivere la query è il seguente:
Java
db.collection("employees")
.whereGreaterThan("salary", 100000)
.orderBy("salary")
.get()
.addOnSuccessListener(new OnSuccessListener<QuerySnapshot>() {
@Override
public void onSuccess(QuerySnapshot queryDocumentSnapshots) {
// Order results by `experience`
}
});;
Node.js
const querySnapshot = await db.collection('employees')
.where("salary", ">", 100000)
.orderBy("salary")
.get();
// Order results by `experience`
Python
results = db.collection("employees")
.where("salary", ">", 100000)
.order_by("salary")
.stream()
// Order results by `experience`
L'aggiunta di un ordinamento su experience
alla query produrrà lo stesso insieme di documenti ed eviterà di riordinare i risultati sui client, ma la query potrebbe leggere molte più voci di indice estranee rispetto alla query precedente. Questo perché
Firestore preferisce sempre un indice i cui campi indice corrispondono al prefisso della
clausola ORDER BY della query. Se experience
è stato aggiunto alla clausola ORDER BY,
Firestore selezionerà l'indice (experience [...], salary [...])
per il calcolo dei risultati della query. Poiché non ci sono altri vincoli su
experience
, Firestore leggerà tutte le voci di indice della
raccolta employees
prima di applicare il filtro salary
per trovare il set di risultati
finale. Ciò significa che le voci di indice che non soddisfano il filtro salary
vengono comunque lette, aumentando così la latenza e il costo della query.
Prezzi
Le query con filtri di intervallo e disuguaglianza su più campi vengono fatturate in base ai documenti letti e alle voci di indice lette.
Per informazioni dettagliate, consulta la pagina Prezzi.
Limitazioni
Oltre alle limitazioni delle query, tieni presente le seguenti limitazioni prima di utilizzare query con filtri di intervallo e di disuguaglianza su più campi:
- Le query con filtri di intervallo o di disuguaglianza sui campi del documento e solo vincoli di uguaglianza sulla chiave del documento
(__name__)
non sono supportate. - Firestore limita il numero di campi di intervallo o disuguaglianza a 10. Questo per evitare che le query diventino troppo costose da eseguire.
Passaggi successivi
- Scopri di più sull'ottimizzazione delle query.
- Scopri di più su come eseguire query semplici e composte.
- Scopri come Firestore utilizza gli indici.