Elasticsearch: _type-Mapping zur Dateninspektion

Keine Kommentare

Problemsituation

Eine typische Situation: Daten aus einer Domän mit verschiedenen Sub-Domänen liegen in stark unterschiedlicher und unbekannter Form, mit ebenso unterschiedlichen und unbekannten Werten, vor. Sich mit diesen Daten auseinanderzusetzen ist kostspielig und undankbar. Lassen sich diese Daten jedoch beispielsweise anhand der Domänen klassifizieren, so hilft die Mapping-Information des Types in Elasticsearch.

Um diese Problemsituation verständlicher darzustellen, wird folgende Beispiel-Domäne verwendet:
Es liegen Artikeldaten vor. Diese Artikel sind in verschiedene (Unter-)Sortimente klassifiziert, die einer Nummerung unterliegen. Jeder Artikel verfügt über eine Menge von Eigenschaften, die allgemeingültig sind. Andere Eigenschaften unterscheiden sich stark je Artikel und (Unter-)Sortiment. Außerdem sind sie unstrukturiert.

Lösung

Schema

Der hier beschriebene Lösungsansatz besteht darin, die Hierarchien, die in der Nummerung abgebildet sind, als zusätzliche Information in das Dokument des Objektes einzubetten. Die übergeordnete Nummer, die das Sortiment klassifiziert, wird dabei als Wert für _type genommen. Die unstrukturierten Werte werden als Unterobjekt mit dem Namen values in das Artikeldokument eingefügt:

{
  "_index": "articles",
  "_type": "300500100",
  "_id": "2",
  "_score": 1.0,
  "_source": {
     "description": "Salami",
     "values": {
            "variety": "pork",
            "weight": "100",
            "additives": "preservatives"
     }
  }
}

Grundsätzlich muss bei einem derartigen Ansatz darauf geachtet werden, wie sparse respektive dense die vorliegenden Daten sind. Sind die Daten innerhalb des Index sparse, kann es zu Performance-Problemen kommen. Weitere Informationen dazu finden sich hier.

Data Inspection

Die Data Inspection erfolgt in zwei Schritten. Im ersten Schritt wird das Mapping des Index abgefragt. Im Beispiel nehmen wir dazu an, dass eine ES-Installation mit dem Index articles zur Verfügung steht.

curl http://localhost:9200/articles/_mappings

Das Ergebnis dieser Abfrage entspricht diesem JSON-Dokument. Direkt unter mappings befindet sich der Wert für den jeweiligen _type, z.B. 300500100. Tiefer im Baum befinden sich properties für Wert values, z.B. additives und variety:

{
  "articles": {
    "mappings": {
      "300500100": {
        "properties": {
          "description": {
            "type": "string"
          },
          "values": {
            "properties": {
              "additives": {
                "type": "string"
              },
              "country_of_origin": {
                "type": "string"
              },
              "variety": {
                "type": "string"
              },
              "weight": {
                "type": "string"
              }
            }
          }
        }
      },
      "300500200": {
        "properties": {
          "description": {
            "type": "string"
          },
          "values": {
            "properties": {
              "country_of_origin": {
                "type": "string"
              },
              "variety": {
                "type": "string"
              },
              "veggy": {
                "type": "string"
              },
              "weight": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

Der nächste Schritt besteht darin, dass sowohl der Wert für _type und die jeweiligen Attribut-Namen properties für values gemerkt werden.

Als nächstes wird mit diesen Werten eine Abfrage formuliert, um bspw. eine Aggregation zu erhalten, deren Ergebnis die Attributnamen und die Anzahl der Ausprägungen in dem gegebenen _type enthält.

curl 'http://localhost:9200/articles/300500100/_search' -d '
{
 "size": 0,
 "aggs": {
    "additives":{
      "terms":{
        "field":"values.additives"
      }
    },
    "weight":{
      "terms":{
        "field":"values.weight"
      }
    },
    "variety":{
      "terms":{
        "field":"values.variety"
      }
    },
    "country_of_origin":{
      "terms":{
        "field":"values.country_of_origin"
      }
    }    
  }
}'

Die Abfrage lässt sich erweitern, um die Daten innerhalb eines Untersortiments oder zwischen unterschiedlichen Sortimenten zu evaluieren.

Mit dieser Abfrage können mehrere Untersortimente aggregiert werden. Zuvor müssen die gemerkten Attributnamen miteinander verknüpft werden.

curl 'http://localhost:9200/articles/300500100,300500200/_search?pretty' -d '
{
 "size": 0,
 "aggs": {
    "additives":{
      "terms":{
        "field":"values.additives"
      }
    },
    "weight":{
      "terms":{
        "field":"values.weight"
      }
    },
    "variety":{
      "terms":{
        "field":"values.variety"
      }
    },
    "country_of_origin":{
      "terms":{
        "field":"values.country_of_origin"
      }
    },
    "veggy":{
      "terms":{
        "field":"values.veggy"
      }
    }    
  }
}'

Fazit

Mithilfe des _type-Mappings hat man insbesondere bei unstrukturierten und unbekannten Daten ein einfaches und gleichzeitig mächtiges Werkzeug, um den Datenbestand von kategorisierten Dokumenten zu evaluieren. Die so gewonnenen Informationen können u.a. Aufschluss über Datenqualität geben. Auch Erkenntnisse über die Qualität der vorhandenen Kategorien können abgeleitet werden, um Dokumente zwischen den Kategorien zu verschieben, Kategorien hinzuzufügen oder bestehende zu entfernen, mit anderen zu kombinieren.

Christian Börner-Schulte

Christian Börner-Schulte beschäftigt sich als Senior IT-Consultant mit Microservices auf Spring- und Akka-Basis sowie mit NoSQL und Frontend-Technologien wie React und Redux.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.