Panoramica delle query con filtri per intervallo e disuguaglianza su più campi
Firestore supporta l'utilizzo di filtri di intervallo e di 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-filtro a Firestore.
Filtri di intervallo e disuguaglianza in più campi
La seguente query utilizza filtri per intervallo su popolazione e densità per restituire tutti Città con popolazione superiore a 1.000.000 di persone e densità di popolazione è inferiore a 10.000 persone per unità di area.
Versione web modulare 9
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 per 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 sulle query e sul modello dei dati Firestore.
In Firestore, la clausola ORDER BY
di una query determina quali indici
possono essere utilizzati per eseguire 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, ottimizzare l'ordine dei campi nell'indice. A questo scopo, assicurati che l'indice sia ordinati da sinistra a destra, in modo che la query si distilla in un set di dati impedisce la scansione di voci di indice non necessarie.
Supponiamo di voler cercare in una raccolta di dipendenti per trovare gli Stati Uniti
dipendenti il cui stipendio è superiore a 100.000 dollari e il cui numero di anni di esperienza è
maggiore di 0. In base alla tua conoscenza del set di dati, sai che il vincolo di salario è più selettivo del vincolo di esperienza. L'ideale
che ridurrebbe il numero di scansioni dell'indice sarebbe il
(salary [...], experience [...])
. Quindi, la query che sarebbe veloce
economicamente conveniente ordinerebbe salary
prima del giorno 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 dell'indice per le equazioni seguite dal campo dell'intervallo o dell'inequità più selettivo
Firestore usa i campi all'estrema sinistra di un indice composto per soddisfare le
i vincoli di uguaglianza e il vincolo di intervallo o disuguaglianza, se presente, nel primo campo
della query orderBy()
. Questi vincoli possono ridurre il numero di voci dell'indice esaminate da Firestore. Firestore utilizza i campi rimanenti
dell'indice per soddisfare altri vincoli di intervallo o disuguaglianza della query. Questi
I vincoli non riducono il numero di voci di indice analizzate da Firestore
ma filtra i documenti senza corrispondenza in modo che il numero di
i dati restituiti ai clienti sono ridotti.
Per saperne di più sulla creazione di indici efficienti, consulta le proprietà dell'indice.
Ordina i campi in ordine decrescente di selettivotà del vincolo di query
Per assicurarti che Firestore selezioni l'indice ottimale per la query,
specifica una clausola orderBy()
che ordini i campi in ordine decrescente di selettivo
contenuto dei vincoli della query. Una maggiore selettività corrisponde a un sottoinsieme più piccolo di documenti, mentre una minore selettività corrisponde a un sottoinsieme più grande di documenti. Assicurati che
selezioni i campi di intervallo o disuguaglianza con una selettività più alta prima nell'indice
rispetto ai campi con una selettività più bassa.
Per ridurre al minimo il numero di documenti che Firestore scansiona e restituisce sulla rete, devi sempre ordinare i campi in ordine decrescente di selettivotà dei vincoli di query. Se i risultati non sono nell'ordine richiesto e i valori di risultati previsti è ridotto, puoi implementare la logica lato client e riordinalo come previsto.
Ad esempio, supponiamo che tu voglia cercare tra una raccolta di dipendenti per trovare quelli 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`
Sebbene l'aggiunta di un ordinamento su experience
alla query generi lo stesso insieme di documenti ed eviti di riordinare i risultati sui client, la query potrebbe leggere molte più voci di indice estranee rispetto alla query precedente. Questo perché
Firestore preferisce sempre un indice il cui prefisso dei campi indice corrisponde alla
in ordine decrescente della query. Se experience
venisse aggiunto alla clausola Ordina per,
Firestore selezionerà l'indice (experience [...], salary [...])
per il calcolo dei risultati delle query. Poiché non ci sono altri vincoli
experience
, Firestore leggerà tutte le voci di indice del
Raccolta employees
prima di applicare il filtro salary
per trovare quella finale
insieme di risultati. Ciò significa che le voci di indice che non soddisfano il salary
vengono ancora letti, aumentando così la latenza e il costo della query.
Prezzi
Le query con filtri per intervallo e disuguaglianza su più campi vengono fatturate in base a documenti letti e voci di indice letti.
Per informazioni dettagliate, consulta la pagina Prezzi.
Limitazioni
Oltre alle limitazioni per le query, tieni presente le seguenti limitazioni prima di utilizzando query con filtri per intervallo e disuguaglianza su più campi:
- Query con filtri per intervallo o disuguaglianza nei campi dei documenti e solo con uguaglianza
i vincoli sulla chiave del documento
(__name__)
non sono supportati. - Firestore limita il numero di campi di intervallo o di disuguaglianza a 10. Ciò serve a evitare che le query diventino troppo costose da eseguire.
Passaggi successivi
- Scopri di più sull'ottimizzazione delle query.
- Scopri di più sull'esecuzione di query semplici e composte.
- Scopri come Firestore utilizza gli indici.