Zoeken…


Opmerkingen

Het is gemakkelijk om type als een tabel in een SQL-database te zien, waarbij de index de SQL-database is. Dat is echter geen goede manier om type s te benaderen.

Alles over typen

Typen zijn letterlijk slechts een metagegevensveld dat door Elasticsearch aan elk document is toegevoegd: _type . De bovenstaande voorbeelden hebben twee typen gemaakt: my_type en my_other_type . Dat betekent dat elk document dat aan de typen is gekoppeld, een extra veld heeft dat automatisch wordt gedefinieerd als "_type": "my_type" ; dit wordt geïndexeerd met het document, waardoor het een doorzoekbaar of filterbaar veld wordt , maar het heeft geen invloed op het onbewerkte document zelf, dus uw toepassing hoeft zich er geen zorgen over te maken.

Alle typen leven in dezelfde index en dus in dezelfde collectieve scherven van de index. Zelfs op schijfniveau leven ze in dezelfde bestanden. De enige scheiding die het maken van een tweede type biedt, is logisch. Elk type, of het nu uniek is of niet, moet bestaan in de toewijzingen en al die toewijzingen moeten in uw clusterstatus bestaan. Dit verbruikt geheugen en, als elk type dynamisch wordt bijgewerkt, eet het prestaties op als de toewijzingen veranderen.

Daarom is het een goede gewoonte om slechts één type te definiëren, tenzij u daadwerkelijk andere typen nodig hebt. Het is gebruikelijk om scenario's te zien waarbij meerdere typen wenselijk zijn. Stel je bijvoorbeeld voor dat je een auto-index had. Het kan handig zijn om het op te splitsen in meerdere typen:

  • BMW
  • chevy
  • honda
  • mazda
  • mercedes
  • nissan
  • RangeRover
  • toyota
  • ...

Op deze manier kunt u naar alle auto's zoeken of deze op aanvraag door de fabrikant beperken. Het verschil tussen deze twee zoekopdrachten is zo eenvoudig als:

GET /cars/_search

en

GET /cars/bmw/_search

Wat niet voor de hand ligt voor nieuwe gebruikers van Elasticsearch is dat de tweede vorm een specialisatie van de eerste vorm is. Het wordt letterlijk herschreven om:

GET /cars/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term" : {
            "_type": "bmw"
          }
        }
      ]
    }
  }
}

Het filtert eenvoudig elk document uit dat niet is geïndexeerd met een veld _type waarvan de waarde bmw . Aangezien elk document wordt geïndexeerd met het type als het veld _type , dient dit als een vrij eenvoudig filter. Als in beide voorbeelden daadwerkelijk was gezocht, dan zou het filter worden toegevoegd aan de volledige zoekopdracht.

Daarom is het veel beter om, als de typen identiek zijn, een enkel type te leveren (bijvoorbeeld de manufacturer in dit voorbeeld) en dit effectief te negeren. Geef vervolgens binnen elk document expliciet een veld op met de naam make of een andere naam die u verkiest en filter er handmatig op wanneer u het wilt beperken. Dit verkleint de grootte van uw toewijzingen tot 1/n waarbij n het aantal afzonderlijke typen is. Het voegt nog een veld toe aan elk document, ten voordele van een overigens vereenvoudigde afbeelding.

In Elasticsearch 1.x en 2.x moet een dergelijk veld worden gedefinieerd als

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "string",
        "index": "not_analyzed"
      }
    }
  }
}
  1. De naam is willekeurig.
  2. De naam is willekeurig en kan overeenkomen met de typenaam als u deze ook wilde.

In Elasticsearch 5.x werkt het bovenstaande nog steeds (het is verouderd), maar de betere manier is om te gebruiken:

PUT /cars
{
  "manufacturer": { <1>
    "properties": {
      "make": { <2>
        "type": "keyword"
      }
    }
  }
}
  1. De naam is willekeurig.
  2. De naam is willekeurig en kan overeenkomen met de typenaam als u deze ook wilde.

Typen moeten spaarzaam worden gebruikt binnen uw indices omdat het de index-mappings opzwelt, meestal zonder veel voordeel. Je moet er minstens één hebben, maar er is niets dat zegt dat je er meer dan één moet hebben.

Algemene vragen

  • Wat als ik twee (of meer) typen heb die grotendeels identiek zijn, maar die een paar unieke velden per type hebben?

Op indexniveau is er geen verschil tussen het ene type dat wordt gebruikt met een paar velden die schaars worden gebruikt en tussen meerdere typen die een aantal niet-schaarse velden delen met een paar niet-gedeelde (wat betekent dat het andere type het veld zelfs niet gebruikt (s)).

Anders gezegd: een dun gebruikt veld is schaars over de index, ongeacht de typen . De schaarsheid komt de index niet ten goede, of doet deze ook echt geen pijn, alleen maar omdat deze in een apart type is gedefinieerd.

U moet deze typen gewoon combineren en een apart typeveld toevoegen.

  • Waarom moeten afzonderlijke typen velden op exact dezelfde manier definiëren?

Omdat elk veld eigenlijk maar één keer wordt gedefinieerd op Lucene-niveau, ongeacht hoeveel typen er zijn. Het feit dat typen überhaupt bestaan is een kenmerk van Elasticsearch en het is slechts een logische scheiding.

  • Kan ik afzonderlijke typen definiëren met hetzelfde veld anders gedefinieerd?

Nee. Als u erin slaagt om een manier te vinden om dit te doen in ES 2.x of hoger, moet u een bugrapport openen . Zoals opgemerkt in de vorige vraag, ziet Lucene ze allemaal als een enkel veld, dus er is geen manier om dit op de juiste manier te laten werken.

ES 1.x liet dit achter als een impliciete vereiste, waardoor gebruikers voorwaarden konden creëren waarbij de toewijzingen van een scherf in een index feitelijk verschilden van een andere scherf in dezelfde index. Dit was in feite een race-situatie en het kon tot onverwachte problemen leiden.

Uitzonderingen op de regel

  • Bovenliggende / onderliggende documenten vereisen dat afzonderlijke typen binnen dezelfde index worden gebruikt.
    • De ouder leeft in één type.
    • Het kind leeft in een apart type (maar elk kind leeft in dezelfde scherf als zijn ouder).
  • Extreem niche use cases waarbij het creëren van tonnen indices ongewenst is en de impact van schaarse velden te verkiezen is boven het alternatief.
    • Bijvoorbeeld, de Elasticsearch monitoring plugin, Marvel (1.x en 2.x) of X-Pack Monitoring (5.x +), controleert Elasticsearch zelf op veranderingen in het cluster, knooppunten, indices, specifieke indices (het indexniveau), en zelfs scherven. Het zou elke dag 5+ indices kunnen maken om die documenten met unieke toewijzingen te isoleren of het zou in strijd kunnen zijn met best practices om de clusterbelasting te verminderen door een index te delen (let op: het aantal gedefinieerde toewijzingen is in feite hetzelfde, maar het aantal gecreëerde indices wordt gereduceerd van n tot 1).
    • Dit is een geavanceerd scenario, maar u moet rekening houden met de definities van gedeelde velden voor verschillende typen!

Expliciet een index met een type maken

Voorbeeld gebruikt basis-HTTP, die gemakkelijk kan worden vertaald naar cURL en andere HTTP-toepassingen. Ze komen ook overeen met de Sense- syntaxis, die in Kibana 5.0 wordt hernoemd naar Console.

Opmerking: In het voorbeeld wordt <#> ingevoegd om de aandacht op onderdelen te vestigen. Die moeten worden verwijderd als u het kopieert!

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. Dit maakt de index met behulp van het eindpunt van de index maken.
  2. Dit is het type .
  3. Gedeelde velden van het type s binnen dezelfde index moeten dezelfde definitie hebben! ES 1.x heeft dit gedrag niet strikt afgedwongen, maar het was een impliciete vereiste. ES 2.x en hoger dwingen dit gedrag strikt af.
  4. Unieke velden in type s zijn in orde.

Indexen (of indices) bevatten typen. Typen zijn een handig mechanisme voor het scheiden van documenten, maar ze vereisen dat u - dynamisch / automatisch of expliciet - een toewijzing definieert voor elk type dat u gebruikt. Als u 15 typen in een index definieert, hebt u 15 unieke toewijzingen.

Zie de opmerkingen voor meer informatie over dit concept en waarom u al dan niet typen wilt gebruiken.

Dynamisch een index met een type maken

Voorbeeld gebruikt basis-HTTP, die gemakkelijk kan worden vertaald naar cURL en andere HTTP-toepassingen. Ze komen ook overeen met de Sense- syntaxis, die in Kibana 5.0 wordt hernoemd naar Console.

Opmerking: In het voorbeeld wordt <#> ingevoegd om de aandacht op onderdelen te vestigen. Die moeten worden verwijderd als u het kopieert!

DELETE /my_index <1>

PUT /my_index/my_type/abc123 <2>
{
  "field1" : 1234, <3>
  "field2" : 456,
  "object1" : {
    "field1" : 7.8 <4>
  }
}
  1. Als het al bestaat (vanwege een eerder voorbeeld), verwijdert u de index.
  2. Indexeer een document in de index, my_index , met het type, my_type en de ID abc123 (kan numeriek zijn, maar het is altijd een tekenreeks).
    • Standaard wordt dynamische indexcreatie ingeschakeld door eenvoudig een document te indexeren. Dit is geweldig voor ontwikkelomgevingen, maar het is niet noodzakelijkerwijs goed voor productieomgevingen.
  3. Dit veld is een geheel getal, dus het moet de eerste keer worden afgebeeld. Elasticsearch gaat altijd uit van het breedste type voor elk inkomend type, dus dit wordt toegewezen als een long plaats van een integer of een short (beide kunnen 1234 en 456 bevatten).
  4. Hetzelfde geldt ook voor dit veld. Het wordt in kaart gebracht als een double plaats van een float zoals u misschien wilt.

Deze dynamisch gemaakte index en dit type komen ruwweg overeen met de toewijzing die in het eerste voorbeeld is gedefinieerd. Het is echter van cruciaal belang om te begrijpen hoe <3> en <4> de automatisch gedefinieerde toewijzingen beïnvloeden.

Je kunt dit volgen door nog een ander type dynamisch aan dezelfde index toe te voegen:

PUT /my_index/my_other_type/abc123 <1>
{
  "field1": 91, <2>
  "field3": 4.567
}
  1. Het type is het enige verschil met het bovenstaande document. De ID is hetzelfde en dat is prima! Het heeft geen relatie met de andere abc123 behalve dat het toevallig in dezelfde index voorkomt .
  2. field1 bestaat al in de index, dus dit moet hetzelfde type veld zijn als gedefinieerd in de andere typen. Het verzenden van een waarde die een string was of geen geheel getal zou mislukken (bijv. "field1": "this is some text" of "field1": 123.0 ).

Hiermee worden de toewijzingen voor my_other_type dynamisch my_other_type binnen dezelfde index, my_index .

Opmerking: het is altijd sneller om toewijzingen vooraf te definiëren in plaats van dat Elasticsearch dit dynamisch uitvoert tijdens het indexeren.

Het eindresultaat van het indexeren van beide documenten zou vergelijkbaar zijn met het eerste voorbeeld, maar de veldtypen zouden anders zijn en daarom enigszins verspillend:

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. Dit gebruikt het eindpunt _mappings om de toewijzingen op te halen uit de index die we hebben gemaakt.
  2. We hebben my_type dynamisch gemaakt in de eerste stap van dit voorbeeld.
  3. field2 is nu een long plaats van een integer omdat we het niet vooraf hebben gedefinieerd. Dit kan verspillend zijn bij schijfopslag.
  4. object1.field1 is nu een double om dezelfde reden als # 3 met dezelfde vertakkingen als # 3.
    • Technisch gezien kan een long in veel gevallen worden gecomprimeerd. Een double kan echter niet worden gecomprimeerd omdat het een drijvende-kommagetal is.
  5. We hebben ook my_other_type dynamisch gemaakt in de tweede stap van dit voorbeeld. De toewijzing ervan is hetzelfde omdat we al long en double .
    • Onthoud dat field1 moet overeenkomen met de definitie van my_type (en dat doet het ook).
    • field3 is uniek voor dit type, dus het heeft geen dergelijke beperking.


Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow