Firestore im Datastore-Modus unterstützt die Verwendung von Bereichs- und Ungleichheitsfiltern für mehrere Attribute in einer einzelnen Abfrage. Mit diesem Feature können Sie Bereichs- und Ungleichheitsbedingungen für mehrere Attribute festlegen und die Anwendungsentwicklung vereinfachen, indem Sie die Implementierung der Logik für das Nachfiltern an Firestore im Datastore-Modus delegieren.
Bereichs- und Ungleichheitsfilter für mehrere Attribute
In der folgenden Abfrage werden Bereichsfilter für „priority“ (Priorität) und „days“ (Tage) verwendet, um alle Aufgaben mit einer Priorität von mehr als vier und weniger als drei Tagen bis zum Abschluss zurückzugeben.
Go
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)
Überlegungen zur Indexierung
Bevor Sie mit dem Ausführen von Abfragen beginnen, sollten Sie sich mit Abfragen vertraut machen.
Wenn keine ORDER BY-Anweisung angegeben ist, verwendet Firestore im Datastore-Modus einen beliebigen Index, der die Filterbedingung der Abfrage erfüllt, um die Abfrage auszuführen. Bei diesem Ansatz wird ein Ergebnissatz erstellt, der gemäß der Indexdefinition sortiert ist.
Um die Leistung und Kosten von Firestore im Datastore-Modus-Abfragen zu optimieren, optimieren Sie die Reihenfolge der Attribute im Index. Dazu muss Ihr Index von links nach rechts sortiert sein, damit die Abfrage auf einen Datensatz reduziert wird, der das Scannen von unnötigen Indexeinträgen verhindert.
Angenommen, Sie möchten in einer Sammlung von Mitarbeitern nach US-Mitarbeitern suchen,deren Gehalt mehr als 100.000 $ beträgt und deren Berufserfahrung mehr als 0 Jahre beträgt. Auf Grundlage Ihres Verständnisses des Datasets wissen Sie, dass die Gehaltsbeschränkung selektiver ist als die Beschränkung der Berufserfahrung. Ein Index, der die Anzahl der Indexscans reduziert, ist der (salary [...], experience [...])-Index. Daher wird bei einer schnellen und kostengünstigen Abfrage salary vor experience sortiert, wie im folgenden Beispiel zu sehen ist:
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 Practices für die Optimierung von Indexen
Beachten Sie beim Optimieren von Indexen die folgenden Best Practices.
Abfragen nach Gleichheitsbedingungen und dann nach dem selektivsten Bereichs- oder Ungleichheitsfeld sortieren
Firestore im Datastore-Modus verwendet die am weitesten links stehenden Attribute eines zusammengesetzten Index, um die Gleichheitsbedingungen und die Bereichs- und Ungleichheitsbedingungen (falls vorhanden) für das erste Feld der orderBy()-Abfrage zu erfüllen. Diese Einschränkungen können die Anzahl der Indexeinträge reduzieren, die von Firestore im Datastore-Modus gescannt werden. Firestore im Datastore-Modus verwendet die verbleibenden Eigenschaften des Index, um andere Bereichs- und Ungleichheitsbeschränkungen der Abfrage zu erfüllen. Diese Einschränkungen verringern nicht die Anzahl der Indexeinträge, die von Firestore im Datastore-Modus gescannt werden, aber sie filtern nicht übereinstimmende Entitäten heraus, sodass die Anzahl der Entitäten, die an die Clients zurückgegeben werden, reduziert wird.
Weitere Informationen zum Erstellen effizienter Indexe finden Sie unter Indexstruktur und -definition und Indexe optimieren.
Eigenschaften in absteigender Reihenfolge der Selektivität der Abfrageeinschränkung sortieren
Damit Firestore im Datastore-Modus den optimalen Index für Ihre Abfrage auswählt, geben Sie eine orderBy()-Klausel an, mit der Bereichs- und Ungleichheitsattribute entsprechend der Selektivität ihrer Einschränkungen in Ihrer Abfrage sortiert werden, beginnend mit dem selektivsten. Bei einer höheren Selektivität werden weniger Entitäten abgeglichen, bei einer niedrigeren Selektivität mehr. Ordnen Sie in Ihrem Indexbereichs- und Ungleichheitseigenschaften mit höherer Selektivität vor Eigenschaften mit niedrigerer Selektivität an.
Um die Anzahl der Entitäten zu minimieren, die von Firestore im Datastore-Modus über das Netzwerk gescannt und zurückgegeben werden, sollten Sie Attribute immer in absteigender Reihenfolge der Selektivität der Abfragebeschränkung anordnen. Wenn der Ergebnissatz nicht in der erforderlichen Reihenfolge ist und er voraussichtlich klein ist, können Sie clientseitige Logik implementieren, um ihn entsprechend Ihrer Erwartung neu zu sortieren.
Sie möchten beispielsweise eine Sammlung von Mitarbeitern durchsuchen, um Mitarbeiter in den USA zu finden, deren Gehalt mehr als 100.000 $ beträgt, und die Ergebnisse nach der Berufserfahrung des Mitarbeiters sortieren. Wenn Sie davon ausgehen,dass nur wenige Mitarbeiter ein Gehalt von mehr als 100.000 $ haben, können Sie die Abfrage so schreiben:
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`
Wenn Sie der Abfrage eine Sortierung für experience hinzufügen, erhalten Sie zwar dieselben Entitäten und müssen die Ergebnisse nicht noch einmal auf den Clients sortieren, aber die Abfrage liest möglicherweise viel mehr unnötige Indexeinträge als die vorherige Abfrage. Das liegt daran, dass Firestore im Datastore-Modus immer einen Index bevorzugt, dessen Indexattribute mit der ORDER BY-Klausel der Abfrage übereinstimmen. Wenn experience der ORDER BY-Klausel hinzugefügt wurde, wählt Firestore im Datastore-Modus den (experience [...], salary [...])-Index aus, um die Abfrageergebnisse zu berechnen. Da es keine anderen Einschränkungen für experience gibt, liest Firestore im Datastore-Modus alle Indexeinträge der Sammlung employees, bevor der Filter salary angewendet wird, um das endgültige Ergebnis zu ermitteln. Das bedeutet, dass Indexeinträge, die nicht dem salary-Filter entsprechen, trotzdem gelesen werden, was die Latenz und die Kosten der Abfrage erhöht.
Preise
Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Attribute werden basierend auf den gelesenen Entitäten und Indexeinträgen abgerechnet.
Weitere Informationen finden Sie auf der Seite Preise.
Beschränkungen
Neben den Abfragebeschränkungen sollten Sie die folgenden Einschränkungen beachten, bevor Sie Abfragen mit Bereichs- und Ungleichheitsfiltern für mehrere Attribute verwenden:
- Damit Abfragen nicht zu teuer werden, begrenzt Firestore im Datastore-Modus die Anzahl der Bereichs- oder Ungleichheitsoperatoren auf 10.
Weitere Informationen
- Weitere Informationen zum Optimieren von Abfragen
- Weitere Informationen zum Ausführen einfacher und komplexer Abfragen
- Indexe in Firestore im Datastore-Modus