Elastic Search Reading
10 Elastic Search Concepts you need to learn
A Practical Introduction to Elasticsearch
Begriffe
ELK | (Elastic & Kibana): Elastic Stack: Beinhaltet als GUI Kibana und darunter Elastic Search. |
Index | Ein Daten-Topf innerhalb Elastic Search |
Index Pattern | Index Pattern definieren, welche Indizes, dass für eine Suche/Auswertung berücksichtigt werden sollen. –> Datenbasis In der Kibana Suchmaske is dieser Parameter links oben angegeben. |
Index Template | Dienen als Templates für Indizes, die „rollend“ angelegt werden. Z.B. soll ein Index jeden Tag neu angelegt werden: myindex_20220801, myindex_20220802, … –> Das dazu gehörige Index Pattern wäre dann wahhrscheinlich „myindex*„. |
Beats | Tool zum (z.B. Zeit-ausgelösten) laden von Daten ins ES. |
ECS | Elastic Common Schema Ich glaube hier geht es z.B. darum Feld-Mappings zu erstellen, die dann für mehrere verschiedene Indexe gelten sollen. Z.B. soll ein Feld Namens http.request.method in allen Indexen geleich interpretiert werden. |
Analyzer | Parsed Felder zu Tokens Definition und Zuweisen eines Analysers: –> siehe unten |
Token | Feld das als soches gesucht werden kann. (Alle Inhalte von Feldern können gefunden werden. Nur handelt es sich dann typischerweise um eine Volltext-Suche.) Built-In Analysers <–versus–> Selbst definierte Analyser Volltext-Suche: {„query“:{„match_phrase„:{„field77″:“hans-peter“}}} Spezifische Token-Suche: {„query“:{„term„:{„field77″:“hans-peter“}}} |
HTTP Kommando-Beispiel
Die HTTP-Kommandos können im Menu „Dev Tools“ ausgeführt werden.
Index anlegen:
put /meinIndex
Der so angelegte Index hat (selbst redend) weder Daten, noch Datentypen, not Mappings.
Einen Index anlegen unter Mitgabe von Datentypdefinitionen:
put meinIndex/
{
"settings":{
"analysis": {
"analyser": {
"my_url_pattern_analyzer": {
"type": "pattern",
"pattern": "\\/|\\?"
}
}
}
},
"mappings": {
"properties": {
"url.original": {
"type": "text",
"analyser": "my_url_pattern_analyzer"
},
"destination.ip": {"type":"ip"},
"destination.port": {"type": "integer"},
"message": {
"type": "text",
"analyser": "keyword"
}
}
}
}
Obiges erstellt einen neuen Index Namens „meinIndex“.
Er enthält die Felder:
- url.original, welches mit dem (weiter oben selber definierten) Analyser in Tokens geparsed werden soll
- destination.ip vom Typ IP (Auf IP Typ Felder kann mit IP-Masken (z.B. 10.0.0.0/24) gesucht werden)
- destistination.port vom Typ Integer
- message vom (default) Typ Text, mit dem zugewiesenen (built in) Analyser „keyword“, welcher den ganzen Feld-Inhalt in ein einziges Token umwandelt.
Token: Sind Werte, nach denen schnell (indexiert?) gesucht werden kann (schneller als Volltextsuche).
Implizites Anlegen des Index beim Daten laden
Besteht ein Index noch nicht in den Daten geladen werden sollen, dann wird der Index implizit angelegt.
Ändern von Datentypen eines Index
put meinIndex
{
"mappings":{
"properties":{
"destination.ip":{"type":"ip"},
"destination.port":{"type":"integer"},
"message":{"type":"text"}
}
}
}
Laden von Daten ins ES
curl -xpost http://elastic-node/meinIndex/_doc
-H 'content-Type: application/json'
-d'
{
"@timestamp" : "2021-01-05T10:10:10",
"message" : "Protocal Prort Mis-Match",
"dst" : {
"ip" : "192.168.1.56",
"port" : "9090"
}
}
'
Update von Werten eine Dokuments
put meinIndex/_doc/DOCKKEY030303020
{
"field7" : "Value new"
}
Analyser ausführen
get /_analyse
{
"analyser" : "standard",
"text" : "www.lodrie.com/wp-container/xdn/do.php?cmd=dldl"
}
Der built-in „standard“ Analyser wird über den „text“ gejagt.
Spezifische Feld-Auswahl bei CriteriaAPI Mehrfach-Joins
Folgendes Beispiel zeigt, wie man spezifische Felder aus einem Join für die Resultat-Tabelle selektiert, indem man eine eingene Empfängerklasse (hier Container) definiert und in CriteriaQuery.multiselect(..) die felder selektiert, die man eben in der Resultattabelle haben will.
Gelehrt hat mich dies diese Stackoverflow-Seite.
/**
* Container, dem das spezifisch selektierten Feld übergeben wird
*/
public static class Container {
private String orderList;
private String businessCd;
/**
* CriteriaAPI übergibt an den Constructor.
*/
public Container(String orderList, String businessCd) {
this.orderList = orderList;
this.businessCd = businessCd;
}
public String getOrderList() {
return orderList;
}
public String getBusinessCd() {
return businessCd;
}
}
/**
* Class getting the data
*/
class GetTheData {
Set<String> getWithCriteriApiExercise(UniqueId businessExecutionId) {
CriteriaBuilder criteriaBuilder = daoProvider.getEntityManager().getCriteriaBuilder();
CriteriaQuery<Container> query = criteriaBuilder.createQuery(Container.class); // <-- !!! selbst definierte Empängerklasse (Container.class)
Root<HpsBusiness> root = query.from(HpsBusiness.class);
Join<HpsBusiness, HpsBusinessExec> joinBusiness = root.join(HpsBusiness._ATTR_businessExec, JoinType.INNER); //n:1
Join<HpsBusiness, HpsExcludedPos> joinExcludedPos = root.join(HpsBusiness._ATTR_excludedPosList, JoinType.INNER); //1:n
query.multiselect(joinExcludedPos.get(HpsExcludedPos._ATTR_orderIdList), root.get(HpsBusiness._ATTR_businessCd)) // <-- !!! multiselect Methode benutzen!!
.where(criteriaBuilder.and(criteriaBuilder.equal(joinBusiness.get(HpsBusinessExec._ATTR_id), businessExecutionId),
criteriaBuilder.equal(joinExcludedPos.get(HpsExcludedPos._ATTR_reason), "deprecated")));
TypedQuery<Container> typedQuery = daoProvider.getEntityManager().createQuery(query);
return typedQuery.getResultList().stream().map(c -> c.getOrderList() + "/" + c.getBusinessCd()).collect(Collectors.toSet()); // get the fields from Container
}
}
Mehrfach-Join in CriteriaAPI
Beachte, dass bei den Joins sowohl in richtung n:1 als auch in Richtung 1:n (mit _ATTR_excludedPosList) referenziert wird!
Set<String> getBusinessTypesWithExclusions(UniqueId businessExecutionId) { CriteriaBuilder criteriaBuilder = daoProvider.getEntityManager().getCriteriaBuilder(); CriteriaQuery<HpsBusiness> query = criteriaBuilder.createQuery(HpsBusiness.class); Root<HpsBusiness> root = query.from(HpsBusiness.class); Join<HpsBusiness, HpsBusinessExec> joinBusiness = root.join(HpsBusiness._ATTR_businessExec, JoinType.INNER); // <-- n : 1 Join<HpsBusiness, HpsExcludedPos> joinExcludedPos = root.join(HpsBusiness._ATTR_excludedPosList, JoinType.INNER); // <-- 1 : n query.select(root).where(criteriaBuilder.and(criteriaBuilder.equal(joinBusiness.get(HpsBusinessExec._ATTR_id), businessExecutionId), criteriaBuilder.equal(joinExcludedPos.get(HpsExcludedPos._ATTR_exclusionReasonType), ExclusionReasonType.EXCLUDED.name()))); return daoProvider.getHpsBusinessDao().find(query).stream().map(HpsBusiness::getBusinessCd).collect(Collectors.toSet()); }