Elasticsearch
Verschil tussen indices en typen
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"
}
}
}
}
- De naam is willekeurig.
- 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"
}
}
}
}
- De naam is willekeurig.
- 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
ntot 1). - Dit is een geavanceerd scenario, maar u moet rekening houden met de definities van gedeelde velden voor verschillende typen!
- 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
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"
}
}
}
}
- Dit maakt de
indexmet behulp van het eindpunt van deindexmaken. - Dit is het
type. - Gedeelde velden van het
types binnen dezelfdeindexmoeten 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. - Unieke velden in
types 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>
}
}
- Als het al bestaat (vanwege een eerder voorbeeld), verwijdert u de index.
- Indexeer een document in de index,
my_index, met het type,my_typeen de IDabc123(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.
- 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
longplaats van eenintegerof eenshort(beide kunnen1234en456bevatten). - Hetzelfde geldt ook voor dit veld. Het wordt in kaart gebracht als een
doubleplaats van eenfloatzoals 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
}
- 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
abc123behalve dat het toevallig in dezelfde index voorkomt . -
field1bestaat 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"
}
}
}
}
- Dit gebruikt het eindpunt
_mappingsom de toewijzingen op te halen uit de index die we hebben gemaakt. - We hebben
my_typedynamisch gemaakt in de eerste stap van dit voorbeeld. -
field2is nu eenlongplaats van eenintegeromdat we het niet vooraf hebben gedefinieerd. Dit kan verspillend zijn bij schijfopslag. -
object1.field1is nu eendoubleom dezelfde reden als # 3 met dezelfde vertakkingen als # 3.- Technisch gezien kan een
longin veel gevallen worden gecomprimeerd. Eendoublekan echter niet worden gecomprimeerd omdat het een drijvende-kommagetal is.
- Technisch gezien kan een
- We hebben ook
my_other_typedynamisch gemaakt in de tweede stap van dit voorbeeld. De toewijzing ervan is hetzelfde omdat we allongendouble.- Onthoud dat
field1moet overeenkomen met de definitie vanmy_type(en dat doet het ook). -
field3is uniek voor dit type, dus het heeft geen dergelijke beperking.
- Onthoud dat