Elasticsearch
Unterschied zwischen Indizes und Typen
Suche…
Bemerkungen
Es ist leicht, type wie eine Tabelle in einer SQL-Datenbank zu sehen, wobei der index die SQL-Datenbank ist. Dies ist jedoch keine gute Möglichkeit, sich dem type s zu nähern.
Alles über Typen
Tatsächlich sind Typen buchstäblich nur ein Metadatenfeld, das jedem Dokument von Elasticsearch hinzugefügt wird: _type . In den obigen Beispielen wurden zwei Typen erstellt: my_type und my_other_type . Das bedeutet, dass jedes Dokument, das den Typen zugeordnet ist, ein zusätzliches Feld hat, das automatisch wie "_type": "my_type" ; Dieses Dokument wird mit dem Dokument indiziert, wodurch es zu einem durchsuchbaren oder filterbaren Feld wird. Es hat jedoch keine Auswirkungen auf das Rohdokument selbst, sodass sich Ihre Anwendung nicht darum kümmern muss.
Alle Typen leben in demselben Index und daher in denselben gemeinsamen Shards des Index. Selbst auf der Festplattenebene leben sie in den gleichen Dateien. Die einzige Trennung, die das Erstellen eines zweiten Typs bietet, ist eine logische. Jeder Typ, unabhängig davon, ob er eindeutig ist oder nicht, muss in den Mappings vorhanden sein, und alle diese Mappings müssen in Ihrem Clusterstatus vorhanden sein. Dies frisst Speicher und wenn jeder Typ dynamisch aktualisiert wird, nimmt die Leistung ab, wenn sich die Zuordnungen ändern.
Daher empfiehlt es sich, nur einen einzigen Typ zu definieren, es sei denn, Sie benötigen tatsächlich andere Typen. Es werden häufig Szenarien angezeigt, in denen mehrere Typen wünschenswert sind. Stellen Sie sich beispielsweise vor, Sie hätten einen Autoindex. Es kann für Sie nützlich sein, es mit mehreren Typen aufzuschlüsseln:
- BMW
- chevy
- Honda
- Mazda
- Mercedes
- Nissan
- Rangerover
- Toyota
- ...
Auf diese Weise können Sie nach allen Fahrzeugen suchen oder sie nach Hersteller einschränken. Der Unterschied zwischen diesen beiden Suchen ist so einfach:
GET /cars/_search
und
GET /cars/bmw/_search
Was für neue Benutzer von Elasticsearch nicht offensichtlich ist, ist, dass die zweite Form eine Spezialisierung der ersten Form ist. Es wird buchstäblich umgeschrieben in:
GET /cars/_search
{
"query": {
"bool": {
"filter": [
{
"term" : {
"_type": "bmw"
}
}
]
}
}
}
Es filtert einfach alle Dokumente heraus, die nicht mit einem _type Feld mit dem Wert bmw . Da jedes Dokument mit seinem Typ als _type Feld indiziert wird, dient dies als ziemlich einfacher Filter. Wenn in einem der Beispiele eine tatsächliche Suche bereitgestellt wurde, wird der Filter entsprechend der vollständigen Suche hinzugefügt.
Wenn also die Typen identisch sind, ist es viel besser, einen einzigen Typ (z. B. manufacturer in diesem Beispiel) bereitzustellen und ihn effektiv zu ignorieren. Geben Sie dann in jedem Dokument explizit ein Feld mit dem Namen make oder einen beliebigen Namen an und filtern Sie es manuell, wann immer Sie es einschränken möchten. Dadurch wird die Größe Ihrer Zuordnungen auf 1/n reduziert, wobei n die Anzahl der separaten Typen ist. Es fügt jedem Dokument ein weiteres Feld hinzu, da sonst die Zuordnung vereinfacht wird.
In Elasticsearch 1.x und 2.x sollte ein solches Feld als definiert werden
PUT /cars
{
"manufacturer": { <1>
"properties": {
"make": { <2>
"type": "string",
"index": "not_analyzed"
}
}
}
}
- Der Name ist beliebig.
- Der Name ist beliebig und könnte mit dem Typnamen übereinstimmen, wenn Sie es auch wollten.
In Elasticsearch 5.x funktioniert das oben immer noch (es ist veraltet), aber der bessere Weg ist zu verwenden:
PUT /cars
{
"manufacturer": { <1>
"properties": {
"make": { <2>
"type": "keyword"
}
}
}
}
- Der Name ist beliebig.
- Der Name ist beliebig und könnte mit dem Typnamen übereinstimmen, wenn Sie es auch wollten.
Typen sollten in Ihren Indizes sparsam verwendet werden, da sie die Indexzuordnungen aufblähen, normalerweise ohne großen Nutzen. Sie müssen mindestens eine haben, aber es gibt nichts, was besagt, dass Sie mehr als eine haben müssen.
Häufige Fragen
- Was ist, wenn ich zwei (oder mehr) Typen habe, die größtenteils identisch sind, jedoch einige eindeutige Felder pro Typ haben?
Auf der Indexebene gibt es keinen Unterschied zwischen einem Typ, der mit wenigen Feldern verwendet wird, die spärlich verwendet werden, und zwischen mehreren Typen, die eine Reihe von nicht-spärlichen Feldern mit einigen nicht gemeinsam genutzten Feldern verwenden (dh der andere Typ verwendet das Feld niemals selbst) (s)).
Anders gesagt: Ein spärlich genutztes Feld ist unabhängig vom Typ im Index spärlich. Die Sparsity ist für den Index nicht von Vorteil oder schadet ihm nicht, nur weil er in einem separaten Typ definiert ist.
Sie sollten diese Typen nur kombinieren und ein separates Typenfeld hinzufügen.
- Warum müssen separate Typen Felder genau gleich definieren?
Denn jedes Feld wird auf Lucene-Ebene wirklich nur einmal definiert, unabhängig davon, wie viele Typen vorhanden sind. Die Tatsache, dass Typen überhaupt existieren, ist ein Merkmal von Elasticsearch und ist nur eine logische Trennung.
- Kann ich separate Typen definieren, bei denen das gleiche Feld anders definiert ist?
Wenn Sie in ES 2.x oder höher einen Weg finden, sollten Sie einen Fehlerbericht öffnen . Wie bereits in der vorigen Frage erwähnt, betrachtet Lucene sie alle als ein einziges Feld, so dass es keine Möglichkeit gibt, diese Arbeit angemessen zu gestalten.
ES 1.x beließ dies als eine implizite Anforderung, die es Benutzern ermöglichte, Bedingungen zu erstellen, bei denen die Zuordnungen eines Shards in einem Index tatsächlich von einem anderen Shard im selben Index abweichen. Dies war effektiv eine Wettlaufsituation und konnte zu unerwarteten Problemen führen.
Ausnahmen von der Regel
- Übergeordnete / untergeordnete Dokumente erfordern die Verwendung separater Typen innerhalb desselben Index.
- Der Elternteil lebt in einem Typ.
- Das Kind lebt in einem separaten Typ (aber jedes Kind lebt in demselben Shard wie sein Elternteil).
- Extrem Nischenanwendungen, bei denen die Erstellung von Tonnen von Indizes unerwünscht ist und die Auswirkung spärlicher Felder der Alternative vorzuziehen ist.
- Das Elasticsearch Monitoring-Plugin Marvel (1.x und 2.x) oder X-Pack Monitoring (5.x +) überwacht Elasticsearch selbst auf Änderungen im Cluster, Knoten, Indizes, bestimmte Indizes (Indexebene), und sogar Scherben. Es könnten täglich mehr als 5 Indizes erstellt werden, um die Dokumente mit eindeutigen Zuordnungen zu isolieren, oder es kann gegen bewährte Methoden verstoßen, um die Clusterlast durch die gemeinsame Nutzung eines Index zu reduzieren (Hinweis: Die Anzahl der definierten Zuordnungen ist praktisch die gleiche, jedoch die Anzahl der erstellten Indizes wird von
nauf 1) reduziert. - Dies ist ein erweitertes Szenario, aber Sie müssen die gemeinsam genutzten Felddefinitionen über Typen hinweg berücksichtigen!
- Das Elasticsearch Monitoring-Plugin Marvel (1.x und 2.x) oder X-Pack Monitoring (5.x +) überwacht Elasticsearch selbst auf Änderungen im Cluster, Knoten, Indizes, bestimmte Indizes (Indexebene), und sogar Scherben. Es könnten täglich mehr als 5 Indizes erstellt werden, um die Dokumente mit eindeutigen Zuordnungen zu isolieren, oder es kann gegen bewährte Methoden verstoßen, um die Clusterlast durch die gemeinsame Nutzung eines Index zu reduzieren (Hinweis: Die Anzahl der definierten Zuordnungen ist praktisch die gleiche, jedoch die Anzahl der erstellten Indizes wird von
Einen Index explizit mit einem Typ erstellen
Beispiel verwendet grundlegende HTTP-Funktionen, die leicht in cURL und andere HTTP-Anwendungen übersetzt werden können. Sie stimmen auch mit der Sense- Syntax überein, die in Kibana 5.0 in Console umbenannt wird.
Hinweis: Das Beispiel fügt <#> , um die Aufmerksamkeit auf Teile zu lenken. Die sollten entfernt werden, wenn Sie es kopieren!
PUT /my_index <1>
{
"mappings": {
"my_type": { <2>
"properties": {
"field1": {
"type": "long"
},
"field2": {
"type": "integer"
},
"object1": {
"type": "object",
"properties": {
"field1" : {
"type": "float"
}
}
}
}
}
},
"my_other_type": {
"properties": {
"field1": {
"type": "long" <3>
},
"field3": { <4>
"type": "double"
}
}
}
}
- Dies erstellt den
indexVerwendung des Endpunkts zum Erstellen des Index. - Dadurch wird der
type. - Freigegebene Felder in
typeinnerhalb desselbenindexmüssen dieselbe Definition haben! ES 1.x hat dieses Verhalten nicht strikt durchgesetzt, es war jedoch eine implizite Anforderung. ES 2.x und höher setzen dieses Verhalten strikt durch. - Eindeutige Felder über
typesind in Ordnung.
Indizes (oder Indizes) enthalten Typen. Typen sind ein praktischer Mechanismus zum Trennen von Dokumenten. Sie müssen jedoch entweder dynamisch / automatisch oder explizit ein Mapping für jeden verwendeten Typ definieren. Wenn Sie 15 Typen in einem Index definieren, haben Sie 15 eindeutige Zuordnungen.
In den Anmerkungen finden Sie weitere Details zu diesem Konzept und warum Sie Typen verwenden möchten oder nicht.
Dynamisches Erstellen eines Index mit einem Typ
Beispiel verwendet grundlegende HTTP-Funktionen, die leicht in cURL und andere HTTP-Anwendungen übersetzt werden können. Sie stimmen auch mit der Sense- Syntax überein, die in Kibana 5.0 in Console umbenannt wird.
Hinweis: Das Beispiel fügt <#> , um die Aufmerksamkeit auf Teile zu lenken. Die sollten entfernt werden, wenn Sie es kopieren!
DELETE /my_index <1>
PUT /my_index/my_type/abc123 <2>
{
"field1" : 1234, <3>
"field2" : 456,
"object1" : {
"field1" : 7.8 <4>
}
}
- Falls es bereits existiert (aufgrund eines früheren Beispiels), löschen Sie den Index.
- Indizieren
my_indexein Dokument in den Index,my_index, mit dem Typ,my_typeund der IDabc123(kann numerisch sein, ist jedoch immer eine Zeichenfolge).- Die dynamische Indexerstellung wird standardmäßig durch einfaches Indizieren eines Dokuments aktiviert. Dies ist ideal für Entwicklungsumgebungen, aber nicht unbedingt für Produktionsumgebungen.
- Dieses Feld ist eine ganze Zahl. Wenn es zum ersten Mal angezeigt wird, muss es zugeordnet werden. Elasticsearch nimmt für jeden eingehenden Typ immer den breitesten Typ an, daher würde dieser als
longstatt alsintegerodershortabgebildet werden (beide können1234und456). - Dasselbe gilt auch für dieses Feld. Es wird als
doublenicht alsfloatabgebildet, wie Sie möchten.
Dieser dynamisch erstellte Index und Typ entspricht in etwa dem im ersten Beispiel definierten Mapping. Es ist jedoch wichtig zu verstehen, wie sich <3> und <4> auf die automatisch definierten Zuordnungen auswirken.
Sie können dem folgen, indem Sie dynamisch einen anderen Typ zu demselben Index hinzufügen:
PUT /my_index/my_other_type/abc123 <1>
{
"field1": 91, <2>
"field3": 4.567
}
- Der Typ ist der einzige Unterschied zum obigen Dokument. Die ID ist die gleiche und das ist in Ordnung! Es hat keine Beziehung zu dem anderen
abc123außer dass es zufällig im selben Index liegt. -
field1bereits im Index vorhanden ist, muss es sich um denselbenfield1, der in den anderen Typen definiert ist. Das Senden eines Werts, der eine Zeichenfolge oder keine Ganzzahl ist,"field1": "this is some text"fehl (z. B."field1": "this is some text"oder"field1": 123.0).
Dadurch würden dynamisch die Zuordnungen für my_other_type innerhalb desselben Index my_index .
Hinweis: Es ist immer schneller, Zuordnungen vorab zu definieren, anstatt sie von Elasticsearch zur Indexzeit dynamisch ausführen zu lassen.
Das Endergebnis der Indizierung beider Dokumente wäre dem ersten Beispiel ähnlich, die Feldtypen wären jedoch unterschiedlich und daher etwas verschwenderisch:
GET /my_index/_mappings <1>
{
"mappings": {
"my_type": { <2>
"properties": {
"field1": {
"type": "long"
},
"field2": {
"type": "long" <3>
},
"object1": {
"type": "object",
"properties": {
"field1" : {
"type": "double" <4>
}
}
}
}
}
},
"my_other_type": { <5>
"properties": {
"field1": {
"type": "long"
},
"field3": {
"type": "double"
}
}
}
}
- Hierbei wird der Endpunkt
_mappings, um die Zuordnungen aus dem von uns erstellten Index_mappings. - Im ersten Schritt dieses Beispiels haben wir
my_typedynamisch erstellt. -
field2ist jetzt einlongstatt einerintegerda wir es nicht im Voraus definiert haben. Dies kann sich als verschwenderisch beim Festplattenspeicher erweisen. -
object1.field1ist jetzt aus dem gleichen Grund wie # 3 mit den gleichen Auswirkungen wie # 3 eindouble.- Technisch kann ein
longin vielen Fällen komprimiert werden. Eindoublekann jedoch nicht komprimiert werden, da es sich um eine Fließkommazahl handelt.
- Technisch kann ein
- Im zweiten Schritt dieses Beispiels haben wir auch
my_other_typedynamisch erstellt. Die Abbildung ist zufällig gleich, weil wir bereitslongunddouble.- Denken
field1daran, dassfield1mit der Definition vonmy_typefield1muss (und dies auch tut). -
field3ist für diesen Typ einzigartig, daher gibt es keine solche Einschränkung.
- Denken