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"
      }
    }
  }
}
  1. Der Name ist beliebig.
  2. 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"
      }
    }
  }
}
  1. Der Name ist beliebig.
  2. 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 n auf 1) reduziert.
    • Dies ist ein erweitertes Szenario, aber Sie müssen die gemeinsam genutzten Felddefinitionen über Typen hinweg berücksichtigen!

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"
      }
    }
  }
}
  1. Dies erstellt den index Verwendung des Endpunkts zum Erstellen des Index.
  2. Dadurch wird der type .
  3. Freigegebene Felder in type innerhalb desselben index mü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.
  4. Eindeutige Felder über type sind 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>
  }
}
  1. Falls es bereits existiert (aufgrund eines früheren Beispiels), löschen Sie den Index.
  2. Indizieren my_index ein Dokument in den Index, my_index , mit dem Typ, my_type und der ID abc123 (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.
  3. 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 long statt als integer oder short abgebildet werden (beide können 1234 und 456 ).
  4. Dasselbe gilt auch für dieses Feld. Es wird als double nicht als float abgebildet, 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
}
  1. 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 abc123 außer dass es zufällig im selben Index liegt.
  2. field1 bereits im Index vorhanden ist, muss es sich um denselben field1 , 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"
      }
    }
  }
}
  1. Hierbei wird der Endpunkt _mappings , um die Zuordnungen aus dem von uns erstellten Index _mappings .
  2. Im ersten Schritt dieses Beispiels haben wir my_type dynamisch erstellt.
  3. field2 ist jetzt ein long statt einer integer da wir es nicht im Voraus definiert haben. Dies kann sich als verschwenderisch beim Festplattenspeicher erweisen.
  4. object1.field1 ist jetzt aus dem gleichen Grund wie # 3 mit den gleichen Auswirkungen wie # 3 ein double .
    • Technisch kann ein long in vielen Fällen komprimiert werden. Ein double kann jedoch nicht komprimiert werden, da es sich um eine Fließkommazahl handelt.
  5. Im zweiten Schritt dieses Beispiels haben wir auch my_other_type dynamisch erstellt. Die Abbildung ist zufällig gleich, weil wir bereits long und double .
    • Denken field1 daran, dass field1 mit der Definition von my_type field1 muss (und dies auch tut).
    • field3 ist für diesen Typ einzigartig, daher gibt es keine solche Einschränkung.


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow