Home » 2021 » März

Archiv für den Monat: März 2021

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.
IndexEin Daten-Topf innerhalb Elastic Search
Index PatternIndex 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 TemplateDienen 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*„.
BeatsTool zum (z.B. Zeit-ausgelösten) laden von Daten ins ES.
ECSElastic 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.
AnalyzerParsed Felder zu Tokens
Definition und Zuweisen eines Analysers: –> siehe unten
TokenFeld 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());
    }