Report-Vorlagen: Daten gruppieren und Aggregieren

Report-Vorlagen: Daten gruppieren und Aggregieren

Diese Funktion wird in der nächsten Version von OpenOlitor verfügbar sein!

Mit der neuen Version steht eine weitere Berichtsfunktionalität zur Verfügung, welche es ermöglicht, Daten zu gruppieren und zu aggregieren.
Beide Funktionen können bspw. Zusammen verwendet werden, um eine Summe der Daten nach einem spezifischen Gruppierungskriterium zu erstellen.
Dazu ein kleines Beispiel:
Uns stehen in einem Bericht folgende Json Daten zur Verfügung:

{
"orders": [
 {
	 "id": "order1",
	 "product": {
		 "id": "1",
		 "name": "Product 1"
	 },
	 "quantity": 12,
	 "price": 123.4
 },
 {
	 "id": "order2",
	 "product": {
		 "id": "2",
		 "name": "Product 2"
	 },
	 "quantity": 14,
	 "price": 45
 },
 {
	 "id": "order3",
	 "product": {
		 "id": "1",
		 "name": "Product 1"
	 },
	 "quantity": 1,
	 "price": 56
 },
 {
	 "id": "order4",
	 "product": {
		 "id": "3",
		 "name": "Product 3"
	 },
	 "quantity": 10,
	 "price": 123.4
 },
 {
	 "id": "order5",
	 "product": {
		 "id": "3",
		 "name": "Product 3"
	 }
 },
 {
	 "id": "order6",
	 "product": {
		 "id": "1",
		 "name": "Product 1"
	 },
	 "quantity": 1,
	 "price": 560
 }
]
}

$GroupBy
Nun soll eine Tabelle erstellt werden welche die verkauften Produkte nach Produkt gruppieren und dabei jeweils die Summe der Menge und des Preises ausrechnen soll.
Dazu wird die Tabelle mit folgendem Namen versehen, welche eine Zeile je Produkttyp erstellt:

$groupBy(product.id,orders)

Der erste Parameter der groupBy Funktion definitiert dabei das Gruppierungskriterium. Der eingetragene JsonPath bezieht sich dabei relativ zu einem Order Element. Der zweite Parameter definiert das Set, über welches Gruppiert werden soll. Auch dieses Attribut entspricht einem JsonPath, entweder relativ zur aktuellen Position im Json Dokument oder absolut. Mit Hilfe des Json Pfades könnte also auch bereits eine Filterung der Elemente vorgenommen werden.

z.B.

$groupBy(product.id,orders[?(@.price > 100)])

Das ganze kann natürlich auch wieder entsprechend sortiert werden:

$groupBy(product.id,orders[?(@.price > 100)])|orderBy:"0.product.id":ASC

Die GroupBy Funktion liefert dabei eine Liste von Listen zurück, welche denselben Gruppierungskriterien entsprechen. Das Resultat dieser Funktion liefert nun also folgendes Json Resultat zurück:

[
  [
    {
      "id": "order4",
      "price": 123.4,
      "product": {
        "id": "3",
        "name": "Product 3"
      },
      "quantity": 10
    }
  ],
  [
    {
      "id": "order1",
      "price": 123.4,
      "product": {
        "id": "1",
        "name": "Product 1"
      },
      "quantity": 12
    },
    {
      "id": "order6",
      "price": 560,
      "product": {
        "id": "1",
        "name": "Product 1"
      },
      "quantity": 1
    }
  ]
]

Das Result entspricht also einer Liste mit zwei Elementen. Das erste Element wiederum entspricht einer Liste von einem Element (Product 3) und das zweite Element einer Liste von zwei Elementen (Product 1), da alle Produkte mit einem Preis < 100 ausgefiltert wurden.
Je Eintrag in der Liste wird also eine neue Zeile erstellt, wobei innerhalb einer Zeile die Werte verwendet werden können.
Soll bspw. Eine Zelle mit dem Produktnamen angezeigt werden, kann wie folgt darauf verwiesen werden:

[0].product.name

Da das Resultat einer Zeile einer Liste entspricht, muss zwingend auf ein Listenelement zugegriffen werden. Da wir aber wissen, dass der Produktname bei allen Produkten gleich lautet, können wir fix auf die erste Listenposition (0) verweisen.
Aggregier-Funktionen
Soll nun innerhalb einer Zeile eine Aggregierung stattfinden, kann eine entsprechende Aggregierfunktion eingesetzt werden.
OpenOlitor unterstützt derzeit folgende Aggregierungsfunktionen:

    • $sum
    • $count
    • $min
    • $max
    • $avg

Um nun eine Summe der Preise in einer Spalte darzustellen, kann nun eine Textbox mit folgendem Namen erstellt werden:

$sum([*].price) 

Damit wird nun die Summer über alle “price” Element in der Liste von Elementen erstellt. Das “$” zu Beginn identifiziert die Funktion und ist nicht mit der Root Referenz “$.” zu verwechseln.
Das Resultat kann natürlich auch wiederum formatiert werden:

$sum([*].price) | number:"#,###.00" 

Das Resultat würde je nach Formatierung in etwa wie folgt aussehen:

Name

Sum

Product 1 683.40
Product 3 123.40