Panoramica delle query con filtri per intervallo e disuguaglianza su più campi

Firestore supporta l'utilizzo di filtri per intervallo e disuguaglianza su più campi in una singola query. Ora puoi avere intervallo condizioni di disuguaglianza in più campi e semplificare dello sviluppo di applicazioni delegando l'implementazione della logica di post-filtro Firestore

Filtri di intervallo e disuguaglianza in più campi

La seguente query restituisce tutti gli utenti la cui età è maggiore di 35 e l'altezza è compresa tra 60 e 70 utilizzando filtri di intervallo per età e altezza.

Versione web modulare 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];

Android Java

 Query query = db.collection("users")
  .whereGreaterThan("age", 35)
  .whereGreaterThan("height", 60)
  .whereLessThan("height", 70);

Kotlin+KTX per Android

 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 aver letto 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 nei campi a ASC, b ASC.

Per ottimizzare le prestazioni e il costo delle query Firestore, dovresti ottimizzare l'ordine dei campi nell'indice. Per farlo, devi assicurarti che l'indice sia ordinato da sinistra a in modo che la query si distilla in un set di dati che impedisce la scansione estranee nell'indice.

Supponiamo che tu voglia cercare in un gruppo di dipendenti e trovare dipendenti il cui stipendio è superiore a 100.000 e il cui numero di anni di esperienza sia maggiore di 0. In base alle tue conoscenze del set di dati, sai che le il vincolo retributivo è più selettivo di quello sull'esperienza. L'ideale che ridurrebbe il numero di scansioni dell'indice sarebbe il (salary [...], experience [...]). Di conseguenza, 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 in base alle uguaglianze seguite dal campo intervallo o disuguaglianza 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 indici che Firestore analizza. 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 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 query, specifica una clausola orderBy() che ordina i campi in ordine decrescente di query selettività del vincolo. Una selettività maggiore corrisponde a un sottoinsieme più piccolo di mentre una selettività più bassa corrisponde a un sottoinsieme più ampio di documenti. Assicurati che selezioni i campi di intervallo o disuguaglianza con una selettività più elevata prima nell'indice rispetto ai campi con una selettività più bassa.

Per ridurre al minimo il numero di documenti che Firestore analizza e restituisce rete, devi sempre ordinare i campi nell'ordine decrescente di selettività del vincolo. 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 in una raccolta di dipendenti per trovare dipendenti il cui stipendio è superiore a 100.000 e ordinano i risultati per l’anno di esperienza del dipendente. Se prevedi che solo un numero limitato di dipendenti avrà uno stipendio oltre 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 set di documenti ed evitare di riordinare i risultati sui client, la query e leggere molte altre 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 disuguaglianza a 10. Questo è per evitare che le query diventino troppo costose eseguire.

Passaggi successivi