Panoramica delle query con filtri di intervallo e disuguaglianza su più campi
Firestore supporta l'uso di filtri di intervallo e disuguaglianza su più campi in una singola query. Ora puoi disporre di condizioni di intervallo e disuguaglianza in più campi e semplificare lo sviluppo dell'applicazione delegando l'implementazione della logica di post-filtro a Firestore.
Filtri di intervallo e disuguaglianza in più campi
La seguente query restituisce tutti gli utenti con un'età superiore a 35 anni e un'altezza compresa tra 60 e 70 anni utilizzando i filtri di intervallo in base all'età e all'altezza.
Web modulare versione 9
const q = query(
collection(db, "users"),
where('age', '>', 35),
where('height', '>', 60),
where('height', '<', 70)
);
Swift
let query = db.collection("users")
.whereField("age", isGreaterThan: 35)
.whereField("height", isGreaterThan: 60)
.whereField("height", isLessThan: 70)
Objective-C
FIRQuery *query =
[[[[self.db collectionWithPath:@"users"]
queryWhereField:@"age" isGreaterThan:@35]
queryWhereField:@"height" isGreaterThan:@60]
queryWhereField:@"height" isLessThan:@70];
Java per Android
Query query = db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70);
Android Kotlin + KTX
val query = db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70)
Java
db.collection("users")
.whereGreaterThan("age", 35)
.whereGreaterThan("height", 60)
.whereLessThan("height", 70);
Node.js
db.collection("users")
.where('age', '>', 35),
.where('height', '>', 60),
.where('height', '<', 70)
Considerazioni sull'indicizzazione
Prima di iniziare a eseguire le query, assicurati di leggere informazioni sulle query e sul modello dei dati di Firestore.
In Firestore, la clausola ORDER BY
di una query determina quali indici
possono essere utilizzati per gestire la query. Ad esempio, una query ORDER BY a ASC, b ASC
richiede un indice composto nei campi a ASC, b ASC
.
Per ottimizzare le prestazioni e il costo delle query Firestore, devi ottimizzare l'ordine dei campi nell'indice. Per farlo, devi assicurarti che l'indice sia ordinato da sinistra a destra in modo che la query venga distillata in un set di dati che impedisca l'analisi di voci di indice estranee.
Supponiamo che tu voglia cercare in un insieme di dipendenti e trovare dipendenti con uno stipendio superiore a 100.000 e con anni di esperienza superiore a 0. In base alla tua comprensione del set di dati, sai che il vincolo di stipendio è più selettivo di quello di esperienza. L'indice ideale che ridurrebbe il numero di scansioni dell'indice sarebbe il valore (salary [...], experience [...])
. Di conseguenza, la query veloce ed economicamente conveniente ordina salary
prima del giorno experience
e appare come segue:
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 in base alle uguaglianze seguiti dall'intervallo o dal campo di disuguaglianza più selettivo
Firestore utilizza i campi più a sinistra di un indice composto per soddisfare i vincoli di uguaglianza e l'intervallo o l'eventuale vincolo di disuguaglianza nel 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 senza corrispondenza in modo da ridurre il numero di documenti restituiti ai client.
Per saperne di più sulla creazione di indici efficienti, consulta la definizione di un indice perfetto.
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 delle query. Una selettività maggiore corrisponde a un sottoinsieme più piccolo di
documenti, mentre una selettività inferiore corrisponde a un sottoinsieme più ampio di documenti. Assicurati di selezionare campi di intervallo o di disuguaglianza con una selettività più elevata all'inizio dell'ordine dell'indice rispetto ai campi con selettività più bassa.
Per ridurre al minimo il numero di documenti che Firestore analizza e restituisce sulla rete, devi sempre ordinare i campi in ordine decrescente di selettività del vincolo di query. Se il set di risultati non è nell'ordine richiesto e dovrebbe essere di dimensioni ridotte, puoi implementare la logica lato client per riordinarlo in base alle tue aspettative di ordinamento.
Ad esempio, supponi di voler cercare in una raccolta di dipendenti per trovare dipendenti con uno 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à uno stipendio superiore 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`
Anche se l'aggiunta di un ordine su experience
alla query restituirà lo stesso insieme di documenti e impedirà il riordinamento dei risultati sui client, la query potrebbe leggere molte più voci di indice non pertinenti rispetto alla query precedente. Questo perché Firestore preferisce sempre un indice il cui prefisso dei campi di indice corrisponde all'ordine per clausola della query. Se experience
viene aggiunto all'ordine per clausola, 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 alla lettura di documenti e alle voci di indice lette.
Per informazioni dettagliate, consulta la pagina dei prezzi.
Limitazioni
Fatta eccezione per le limitazioni delle query, prima di utilizzare le query con filtri di intervallo e disuguaglianza su più campi, tieni presente le seguenti limitazioni:
- Le query con filtri di intervallo o disuguaglianza nei campi del documento e solo vincoli di uguaglianza nella chiave del documento
(__name__)
non sono supportate. - Firestore limita il numero di campi di intervallo o di disuguaglianza a 10. 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 in che modo Firestore utilizza gli indici.