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

Firestore in modalità Datastore supporta l'utilizzo di filtri di intervallo e di disuguaglianza su più proprietà in una singola query. Questa funzionalità ti offre condizioni di intervallo e disuguaglianza su più proprietà e semplifica lo sviluppo delle applicazioni delegando l'implementazione della logica di post-filtro a Firestore in modalità Datastore.

Filtri di intervallo e disuguaglianza su più proprietà

La seguente query utilizza i filtri di intervallo per priorità e giorni per restituire tutte le attività con priorità superiore a quattro e con meno di tre giorni per il completamento.

Vai

query := datastore.NewQuery("Task").
   FilterField("priority", ">", 4).
   FilterField("days", "<", 3).

GQL

SELECT * FROM /tasks WHERE priority > 4 AND days < 3;

Java

Query<Entity> query =
    Query.newEntityQueryBuilder()
      .setKind("Task")
      .setFilter(
        CompositeFilter.and(
            PropertyFilter.gt("priority", 4), PropertyFilter.lt("days", 3)))
    .build();

Node.js

const query = datastore
  .createQuery('Task')
  .filter(
    and([
      new PropertyFilter('priority', '>', 4),
      new PropertyFilter('days', '<', 3),
    ])
  );

Python

from google.cloud import datastore
client = datastore.Client()
query = client.query(kind="Task")
query.add_filter(filter=PropertyFilter("priority", ">", 4))
query.add_filter(filter=PropertyFilter("days", "<", 3))

PHP

$query = $datastore->query()
    ->kind('Task')
    ->filter('priority', '>', 4)
    ->filter('days', '<', 3)

C#

Query query = new Query("Task")
{
  Filter = Filter.And(Filter.GreaterThan("priority", 4),
    Filter.LessThan("days", 3))
};

Ruby

query = datastore.query("Task")
                 .where("priority", ">", 4)
                 .where("days", "<", 3)

Considerazioni sull'indicizzazione

Prima di iniziare a eseguire query, assicurati di aver letto informazioni sulle query.

Se non viene specificata una clausola ORDER BY, Firestore in modalità Datastore utilizza qualsiasi indice che possa soddisfare la condizione di filtro della query per eseguirla. Questo approccio produce un insieme di risultati ordinato in base alla definizione dell'indice.

Per ottimizzare le prestazioni e i costi delle query di Firestore in modalità Datastore, ottimizza l'ordine delle proprietà nell'indice. Per farlo, assicurati che l'indice sia ordinato da sinistra a destra in modo che la query venga distillata in un set di dati che impedisca la scansione di voci di indice estranee.

Ad esempio, supponiamo che tu voglia cercare in una raccolta di dipendenti per trovare quelli 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 conoscenza del set di dati, sai che la limitazione di stipendio è più selettiva rispetto alla limitazione di esperienza. Un indice che riduce il numero di scansioni dell'indice è l'(salary [...], experience [...]). Di conseguenza, una query rapida ed economica ordina salary prima di experience, come mostrato nell'esempio seguente:

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, se presenti, l'intervallo e il vincolo di disuguaglianza nel primo campo della query orderBy(). Questi vincoli possono ridurre il numero di voci dell'indice analizzate da Firestore in modalità Datastore. Firestore in modalità Datastore utilizza le proprietà rimanenti dell'indice per soddisfare altri vincoli di intervallo e disuguaglianza della query. Questi vincoli non riducono il numero di voci dell'indice esaminate da Firestore in modalità Datastore, ma filtrano le entità non corrispondenti in modo da ridurre il numero di entità restituite ai client.

Per ulteriori informazioni sulla creazione di indici efficienti, consulta la sezione Definizione e struttura degli indici e Ottimizzazione degli indici.

Ordina le proprietà in ordine decrescente di selettivotà del vincolo di query

Per assicurarti che Firestore in modalità Datastore selezioni l'indice ottimale per la query, specifica una clausola orderBy() che ordini le proprietà di intervallo e disuguaglianza in base al grado di selettivo dei relativi vincoli nella query, iniziando da quello più selettivo. Una maggiore selettività corrisponde a un numero inferiore di entità, mentre una minore selettività corrisponde a un numero maggiore di entità. Nell'ordinamento dell'indice, inserisci le proprietà di intervallo e disuguaglianza con una maggiore selettività prima di quelle con una selettività inferiore.

Per ridurre al minimo il numero di entità che Firestore in modalità Datastore esegue la scansione e restituisce sulla rete, devi sempre ordinare le proprietà in ordine decrescente di selettivorietà dei vincoli di query. Se il set di risultati non è nell'ordine richiesto e si prevede che sia di piccole dimensioni, puoi implementare la logica lato client per riordinarlo in base alle tue aspettative.

Ad esempio, se vuoi cercare in una raccolta di dipendenti per trovare quelli degli Stati Uniti il cui stipendio è superiore a 100.000 $e ordinarli in base all'anno di esperienza del dipendente. Se prevedi che solo un numero ridotto di dipendenti abbia uno stipendio superiore a 100.000 $, un modo 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`

Sebbene l'aggiunta di un'ordinamento su experience alla query generi lo stesso insieme di entità ed eviti di riordinare i risultati sui client, la query potrebbe leggere molte più voci di indice estranee rispetto alla query precedente. Questo accade perché Firestore in modalità Datastore preferisce sempre un indice il cui prefisso delle proprietà dell'indice corrisponde alla clausola order by della query. Se experience è stato aggiunto alla clausola ORDER BY, Firestore in modalità Datastore selezionerà l'indice (experience [...], salary [...]) per calcolare i risultati della query. Poiché non ci sono altri vincoli su experience, Firestore in modalità Datastore leggerà tutte le voci dell'indice della raccolta employees prima di applicare il filtro salary per trovare il set di risultati finale. Ciò significa che le voci dell'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 di disuguaglianza su più proprietà vengono fatturate in base alle entità lette e alle voci dell'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 disuguaglianza su più proprietà:

  • Per evitare che l'esecuzione delle query diventi troppo costosa, Firestore in modalità Datastore limita il numero di operatori di intervallo o di disuguaglianza a 10.

Passaggi successivi