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

Firestore in modalità Datastore supporta l'utilizzo di filtri di intervallo e 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-filtraggio a Firestore in modalità Datastore.

Filtri di intervallo e disuguaglianza su più proprietà

La seguente query utilizza filtri di intervallo su priorità e giorni per restituire tutte le attività con priorità maggiore di 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 le query, assicurati di aver letto le 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. Questo approccio produce un insieme di risultati ordinato in base alla definizione dell'indice.

Per ottimizzare le prestazioni e il costo delle query di Firestore in modalità Datastore, ottimizza l'ordine delle proprietà nell'indice. A questo scopo, assicurati che l'indice sia ordinato da sinistra a destra in modo che la query si riduca a un insieme di dati che impedisca la scansione di voci di indice estranee.

Supponiamo, ad esempio,di voler cercare in una raccolta di dipendenti per trovare i dipendenti 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 dell'insieme di dati, sai che il vincolo dello stipendio è più selettivo del vincolo dell'esperienza. Un indice che riduce il numero di scansioni dell'indice è l'indice (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 in base alle uguaglianze seguite dal campo di intervallo o disuguaglianza più selettivo

Firestore in modalità Datastore utilizza le proprietà più a sinistra di un indice composto per soddisfare i vincoli di uguaglianza e il vincolo di intervallo e disuguaglianza, se presente, sul primo campo della query orderBy(). Questi vincoli possono ridurre il numero di voci di indice scansionate 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 di indice scansionate 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 pagina relativa alla struttura e alla definizione degli indici e all'ottimizzazione degli indici.

Ordina le proprietà in ordine decrescente di selettività dei vincoli di query

Per assicurarti che Firestore in modalità Datastore selezioni l'indice ottimale per la tua query, specifica una clausola orderBy() che ordini le proprietà di intervallo e disuguaglianza in base alla selettività dei vincoli nella query, a partire da quella più selettiva. Una selettività più elevata corrisponde a un numero inferiore di entità, mentre una selettività inferiore corrisponde a un numero maggiore di entità. Nell'ordinamento degli indici, inserisci le proprietà di intervallo e disuguaglianza con selettività più elevata prima delle proprietà con selettività inferiore.

Per ridurre al minimo il numero di entità scansionate e restituite da Firestore in modalità Datastore sulla rete, devi sempre ordinare le proprietà in ordine decrescente di selettività dei vincoli di query. Se l'insieme di risultati non è nell'ordine richiesto e si prevede che sia piccolo, puoi implementare la logica lato client per riordinarlo in base alle tue aspettative di ordinamento.

Supponiamo, ad esempio,di voler cercare in una raccolta di dipendenti per trovare i dipendenti 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 piccolo numero di dipendenti avrà 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 in base a experience alla query produca 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 perché Firestore in modalità Datastore preferisce sempre un indice le cui proprietà di indice corrispondono al prefisso della clausola order by della query. Se experience viene aggiunto alla clausola order by, Firestore in modalità Datastore selezionerà l'indice (experience [...], salary [...]) per calcolare i risultati della query. Poiché non esistono altri vincoli su experience, Firestore in modalità Datastore leggerà tutte le voci di indice della raccolta employees prima di applicare il filtro salary per trovare l'insieme 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

Oltre alle limitazioni delle query, tieni presente le seguenti limitazioni prima di utilizzare le query con filtri di intervallo e disuguaglianza su più proprietà:

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

Passaggi successivi