Panoramica delle query con filtri di intervallo e disuguaglianza in più proprietà

Firestore in modalità Datastore supporta l'uso di filtri di intervallo e disuguaglianza su più proprietà in una singola query. Ora puoi avere condizioni di intervallo e disuguaglianza su più proprietà e semplificare lo sviluppo dell'applicazione delegando l'implementazione della logica di post-filtro a Firestore in modalità Datastore.

Filtri di intervallo e disuguaglianza su più proprietà

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.

GQL

 SELECT * FROM /users WHERE age > 35 AND height > 60 AND height < 70;

Java


  Query<Entity> query =
    Query.newEntityQueryBuilder()
      .setKind("users")
      .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("age", 35), PropertyFilter.gt("height", 60), PropertyFilter.lt("height", 70)))
    .build();

Considerazioni sull'indicizzazione

Prima di iniziare a eseguire query, assicurati di leggere informazioni sulle query.

Se non viene specificata una clausola ORDER BY, Firestore in modalità Datastore utilizza qualsiasi indice in grado di soddisfare la condizione di filtro della query per pubblicare la query, producendo un set di risultati ordinato in base alla definizione dell'indice.

Per ottimizzare le prestazioni e i costi di Firestore nelle query in modalità Datastore, devi ottimizzare l'ordine delle proprietà 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 l'indice (salary [...], experience [...]). Di conseguenza, la query veloce ed economicamente conveniente ordina salary prima del giorno experience e appare come segue:

GQL

SELECT *
FROM /employees
WHERE salary > 100000 AND experience > 0
ORDER BY salary, experience

Java

Query<Entity> query =
  Query.newEntityQueryBuilder()
    .setKind("employees")
    .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("salary", 100000), PropertyFilter.gt("experience", 0)))
    .setOrderBy(OrderBy("salary"), OrderBy("experience"))
    .build();

Node.js

const query = datastore
  .createQuery("employees")
  .filter(
    and([
      new PropertyFilter("salary", ">", 100000),
      new PropertyFilter("experience", ">", 0),
       ])
    )
  .order("salary")
  .order("experience");

Python

query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.add_filter("experience", ">", 0)
query.order = ["-salary", "-experience"]

Best practice per l'ottimizzazione degli indici

Quando ottimizzi gli indici, tieni presente le seguenti best practice.

Ordina le query per uguaglianza seguite dall'intervallo più selettivo o dal campo di disuguaglianza

Firestore in modalità Datastore utilizza le proprietà più a sinistra di un indice composto per soddisfare i vincoli di uguaglianza e l'eventuale vincolo di intervallo e di disuguaglianza nel primo campo della query orderBy(). Questi vincoli possono ridurre il numero di voci degli indici che Firestore in modalità Datastore analizza. Firestore in modalità Datastore utilizza le restanti proprietà dell'indice per soddisfare altri vincoli di intervallo e disuguaglianza. Questi vincoli non riducono il numero di voci di indice analizzate da Firestore in modalità Datastore, ma filtrano le entità senza corrispondenza in modo da ridurre il numero di entità restituite ai client.

Per saperne di più sulla creazione di indici efficienti, consulta la pagina relativa alla struttura e alla definizione degli indici e all'ottimizzazione degli indici.

Ordine delle proprietà in ordine decrescente di selettività del vincolo di query

Per assicurarti che Firestore in modalità Datastore selezioni l'indice ottimale per la tua query, specifica una clausola orderBy() che ordina le proprietà di intervallo e disuguaglianza in ordine decrescente di selettività del vincolo di query. Una selettività maggiore corrisponde a un sottoinsieme più piccolo di entità, mentre una selettività inferiore corrisponde a un sottoinsieme più ampio di entità. Assicurati di selezionare le proprietà di intervallo e disuguaglianza con una selettività più elevata all'inizio dell'ordine dell'indice rispetto alle proprietà con bassa selettività.

Per ridurre al minimo il numero di entità che Firestore in modalità Datastore analizza e restituisce sulla rete, devi sempre ordinare le proprietà 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

Query<Entity> query =
  Query.newEntityQueryBuilder()
    .setKind("employees")
    .setFilter(PropertyFilter.gt("salary", 100000))
    .setOrderBy(OrderBy("salary"))
    .build();
QueryResults<Entity> results = datastore.run(query);
// Order results by `experience`

Node.js

const query = datastore
  .createQuery("employees")
  .filter(new PropertyFilter("salary", ">", 100000))
  .order("salary");
const [entities] = await datastore.runQuery(query);
// Order results by `experience`

Python

query = client.query(kind="employees")
query.add_filter("salary", ">", 100000)
query.order = ["salary"]
results = query.fetch()
// Order results by `experience`

Anche se l'aggiunta di un ordinamento in experience alla query restituirà lo stesso insieme di entità 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 in modalità Datastore preferisce sempre un indice il cui prefisso delle proprietà dell'indice corrisponde all'ordine per clausola della query. Se experience viene aggiunto all'ordine per clausola, Firestore in modalità Datastore selezionerà l'indice (experience [...], salary [...]) per il calcolo dei risultati della query. Poiché non esistono altri vincoli su experience, Firestore in modalità Datastore legge 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ù proprietà vengono fatturate in base alle entità lette 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ù proprietà, tieni presente le seguenti limitazioni:

  • Firestore in modalità Datastore limita il numero di operatori di intervallo o di disuguaglianza a 10. per evitare che le query diventino troppo costose da eseguire.

Passaggi successivi