Collection Projektion

Projektion - Kurzfassung

Zweck: Sammelte Werte für das Feld der Collection und bindet diese über das Feld für Join in die Suche ein.

images/download/attachments/155419707/image-2023-10-27_14-54-51-version-1-modificationdate-1698411296316-api-v2.png

Eine Collection Projektion liefert eine Liste von Werten aus der Projektion im Parameter Feld der Collection, die in einer über den Parameter Feld für Join definierten Beziehung zur Suche stehen.

  • Liefert die als Feld der Collection konfigurierte Projektion "Kein Wert" ($null), dann wird der Collection kein Eintrag hinzugefügt. Die Collection beinhaltet also ggf. weniger Einträge als die Datenquelle für das Feld für Join bereitstellt. Diese Charakteristik entspricht der für den Sammle Werte-Wertauflöser.
    HINWEIS◄ Weil die Collection $null-Werte ignoriert, kann eine Wenn ( Case ) Projektion kann im Kontext der Konfiguration für das Feld der Collection nützlich sein, um die folgenden Ziele (ggf. auch gleichzeitig) zu erreichen:

    • Anstelle eines $null-Werts in den Originaldaten kann ein konkreter Ersatzwert zugewiesen werden, der innerhalb der Collection "Leerstellen" (bzw. unbestimmte Werte) kennzeichnet.

    • Umgekehrt können konkrete Werte abhängig von einer Bedingung durch "Kein Wert" ($null) ersetzt werden, sodass die Collection nur eine Teilmenge der eigentlich verfügbaren Werte auflistet.

Als Feld für Join ist per Standard das Feld "ID" (id) vorbelegt, da die Collection Projektion typischerweise verwendet wird, um Daten zu sammeln, die in unmittelbarem Bezug zur gesuchten Entität stehen.

Um die Werte für die Collection zu "sammeln" erfolgt intern eine zusätzliche Datenbankabfrage, die Werte für das Feld der Collection in Verbindung mit Schlüsselwerten für das Feld für Join auflistet. Aus dieser "Master-Sammlung" wird über das Feld für Join jeder Entität in der Suche eine bestimmte Teilmenge als Wertliste zugeschlüsselt.


WICHTIG◄ Die im Kontext der Collection Projektion ausgeführte Abfrage zum "Sammeln" von Werten erfolgt ohne Rücksicht auf Zugriffbeschränkungen, die im Kontext einer direkten Suche nach denselben Daten greifen würden. Intern besteht also (wie bei einem vollwertigen Join) Vollzugriff auf alle Instanzen der gesuchten Entität.

Was bedeutet das?

  • Solange für das Feld für Join der Standardwert "ID" (id) ausgewählt ist oder keine Auswahl besteht, ist dies unkritisch, da die Collection Projektion effektiv nur Daten von Instanzen der gesuchten Entität "ausliefert", die auch direkt abgerufen werden könnten.

  • Wenn ein anderes Feld für Join als "ID" (id) ausgewählt wird, kann die Collection Projektion auch Daten von Instanzen "enthüllen", für die kein direkter Zugriff aber eine Beziehung zu einer abrufbaren Entität über das Feld für Join besteht.
    Beispiel: Eine Suche für Firmen verwendet eine Collection Projektion, in der als Feld für Join das Feld "Besitzer" (ownerId) ausgewählt ist. Für jede direkt abrufbare Firma werden dann Werte (aus der als Feld der Collection definierten Projektion) als Liste zugeordnet, die in Verbindung mit irgendeiner Firma gesammelt wurden, die denselben "Besitzer" hat wie die direkt abrufbare Firma (mehr Details s. "Beispiele" unten).


Konfiguration

Parameter

Typ

Beschreibung

Name

String

Der optionale Parameter Name kann verwendet werden, um der Projektion einen (Alias-)Namen zuzuweisen.

  • Wenn kein Name angegeben ist, wird als Spaltenname (sofern relevant) der für das Feld der Collection anwendbare Name durchgereicht.

Feld für Join

String
(Auswahlfeld)

Das Feld für Join bestimmt über welches Feld die als Collection bereitgestellten Werte in den Kontext der Suche eingebunden werden sollen.

Der Parameter Feld für Join definiert einen Pfad zu einem Feld als Zeichenfolge, die per Direkteingabe oder Auswahl aus dem Dropdown festgelegt werden kann (Details s. Feldprojektion, Parameter "Feld").

Ohne Auswahl für das Feld für Join, wird das Feld "ID" (id) verwendet. Dieses Feld ist auch als Standardwert vorbelegt.

Feld der Collection

Projektion

Für den Parameter Feld der Collection können beliebige Projektionen eingesetzt werden. Die Projektion bestimmt, welche Werte gesammelt und dann über das Feld für Join im Kontext der Suche zugeordnet werden.

Beispiele

Einfaches Beispiel: Auflisten der zugeordneten Rollen je Benutzer

Eine Tupel-Suche für Benutzer soll für jeden Benutzer in Verbindung mit dem Feld "Benutzername" (username) eine Liste der im Benutzerkonto zugewiesenen Rollen ausgegeben werden.

Konfiguration:

Der Screenshot zeigt die Konfiguration für die Projektionen der Tupel-Suche:

  • Die Feldprojektion liefert den Textwert im Feld "Benutzername" (username).

  • Die Collection Projektion soll die zugewiesenen Rollen auflisten:

    • Als Feld für Join behalten wir den Standard "ID" (id) bei.

    • Als Feld der Collection wählen wir das Listenfeld "Rollen" (roles) aus, in dem das Benutzerkonto die zugewiesenen Rollen über deren ID-Werte (Long) referenziert.

HINWEIS◄ Wir verzichten auf ausdrückliche Zuordnungen für den Parameter Name in beiden Projektionen, sodass die Feldnamen username und roles die Spalten identifizieren.

images/download/attachments/155419707/image-2023-10-27_19-13-7-version-1-modificationdate-1698426791546-api-v2.png

Laufzeitbeispiel:

Das Ergebnis der Tupel-Suche (rechts) zeigt neben dem Textwert (username) einen Listenwert (roles), der für unterschiedliche Benutzer eine unterschiedlich umfangreiche Auswahl an Rollen über Long-Werte referenziert. Jedem Benutzer werden die ihm zugewiesenen Rollen zugeordnet.

ANMERKUNG◄ Mehr Information zur Rolle bietet das Benutzerkonto selbst nicht an. Per Datenobjekt Join könnten Detaildaten der Rolle einbezogen und dann auch in der Collection Projektion per Feld der Collection berücksichtigt werden.

HINWEIS◄ Das XML-Format verdeutlicht auch, dass die Reihenfolge der entry-Elemente für Listeneinträge "unsortiert" erscheinen. Tatsächlich besteht auch keine Möglichkeit zum Sortieren der in einer Collection-Spalte gesammelten Werte innerhalb der Abfrage. Bei Bedarf muss das Ergebnis also nachträglich aufbereitet werden, soweit möglich.

   <core:TupleSearchResult maxResults="100" count="43">
<columns>
<name>username</name>
<name>roles</name>
</columns>
<result>
<row>
<item xsi:type="xsd:string">adent</item>
<item xsi:type="list">
<entry xsi:type="xsd:long">1401</entry>
<entry xsi:type="xsd:long">501</entry>
</item>
</row>
<row>
<item xsi:type="xsd:string">Q</item>
<item xsi:type="list">
<entry xsi:type="xsd:long">1001</entry>
<entry xsi:type="xsd:long">1</entry>
<entry xsi:type="xsd:long">501</entry>
<entry xsi:type="xsd:long">1201</entry>
               ...
</item>
</row>
...
</result>
</core:TupleSearchResult>

Einfaches Beispiel: Auflisten aller Benutzer mit demselben Besitzer

Eine Tupel-Suche für Benutzer soll in Verbindung mit dem Feld "Benutzername" (username) eine Liste der Benutzernamen aller Benutzer erscheinen, deren Konten sich auf dasselbe Firmenkonto als "Besitzer" (ownerId) beziehen, wie der betreffende Benutzer.

Der Screenshot rechts zeigt die Projektionen für eine Tupel-Suche:

  • Die Feldprojektion gibt das Feld "Benutzername" (username) eines Benutzers (je Zeile) zurück.

  • Die Collection Projektion bezieht sich auf dasselbe Feld "Benutzer" (username) per Feldprojektion im Parameter Feld der Collection.

  • Als Feld für Join ist abweichend vom Standard das Feld "Besitzer" (ownerId) ausgewählt.

  • Der Name "SAME_OWNER" weist auf den Inhalt der Collection hin.

images/download/attachments/155419707/image-2023-10-31_9-42-6-version-1-modificationdate-1698741736190-api-v2.png

Laufzeitbeispiel:

Das Ergebnis der Tupel-Suche (rechts) zeigt neben dem Textwert (username) einen Listenwert (SAME_OWNER), der für unterschiedliche Benutzer die Name aller Benutzer angibt, für die die "Besitzer"-Firma des Benutzers ebenfalls als "Besitzer" gilt.

HINWEIS◄ Wie die Beispieldaten veranschaulichen sollen, taucht der in der username-Spalte ausgegebene Benutzername zwangsläufig immer auch in der Collection auf. Das kann im Kontext der Collection Projektion auch nicht verhindert werden, da die Konfiguration neben dem Feld für Join keine Nebenbedingungen für die Zuordnung der gesammelten Daten vorsieht.

Allerdings kann die Collection Projektion durchaus verwendet werden, um zu erreichen, dass in der SAME_OWNER-Spalte nur andere Benutzernamen erscheinen, als der in der username-Spalte genannte. Wie das geht, zeigt das folgende etwa komplexere Beispiel.

   <core:TupleSearchResult maxResults="100" count="3">
<columns>
<name>username</name>
<name>SAME_OWNER</name>
</columns>
<result>
<row>
<item xsi:type="xsd:string">bbanner</item>
<item xsi:type="list">
<entry xsi:type="xsd:string">pparker</entry>
<entry xsi:type="xsd:string">bbanner</entry>
<entry xsi:type="xsd:string">srogers</entry>
...
</item>
</row>
<row>
<item xsi:type="xsd:string">bwayne</item>
<item xsi:type="list">
<entry xsi:type="xsd:string">bwayne</entry>
<entry xsi:type="xsd:string">ckent</entry>
<entry xsi:type="xsd:string">acurry</entry>
...
</item>
</row>
</result>
...
</core:TupleSearchResult>

Komplexeres Beispiel: Auflisten aller anderen Benutzer mit demselben Besitzer

Abweichend vom vorherigen Beispiel soll erreicht werden, dass der in der username-Spalte ausgegebene "Benutzername" in der zugehörigen Liste in der SAME_OWNER-Spalte nicht erneut genannt wird. Die Liste soll also alle anderen Benutzer mit derselben "Besitzer"-Firma (ownerId) haben.

Konfiguration:

Da innerhalb der Collection Projektion keine beliebigen Bedingungen für die Zuordnung der gesammelten Daten formuliert werden können, müssen wir in unserer Suche einen Datenobjekt Join einrichten, der explizit dazu dient, die anderen Benutzer mit demselben Besitzer zu identifizieren.

Der Datenobjekt Join wird wie rechts abgebildet konfiguriert:

  • Als Datenobjekt ist der Entitätstyp "Benutzer" ausgewählt.

  • Als Join Alias wurde hier willkürlich das Kürzel u2 zugeordnet,

  • Die Join Bedingung prüft zwei Kriterien in einer UND-Verknüpfung:

    • Die erste Feld Einschränkung (id!=u2.id) verhindert, dass der Haupt-Benutzer als u2-Benutzer zurückgegeben wird.

      Dieses Kriterium definiert die Nebenbedingung, die im vorherigen Beispiel innerhalb der Collection Projektion nicht konfiguriert werden konnte.

    • Die zweite Feld Einschränkung (ownerId==u2.ownerId) verlangt, dass alle u2-Benutzer denselben "Besitzer" haben müssen, wie der Haupt-Benutzer.

      Dieses Kriterium entspricht der Feldauswahl von "Besitzer" (ownerId) als Feld für Join in der Collection Projektion im vorherigen Beispiel.

images/download/attachments/155419707/image-2023-10-31_13-47-5-version-1-modificationdate-1698756436579-api-v2.png

Der Screenshot rechts zeigt, die Projektionen, mit denen das gewünschte Ergebnis erzielt werden kann:

  • Die Feldprojektion für die username-Spalte kann unverändert beibehalten werden.

  • Die Collection Projektion für die SAME_OWNER-Spalte verweist jetzt als Feld der Collection per Pfad u2.username auf das "Benutzername"-Feld der über den Datenobjekt Join (u2) einbezogenen Benutzer.

  • Im Feld für Join muss der Standardwert "ID" (id) ausgewählt werden, da (1:n)-Beziehung nun durch den Datenobjekt Join entsteht.

images/download/attachments/155419707/image-2023-10-31_14-7-47-version-1-modificationdate-1698757678683-api-v2.png

Laufzeitbeispiel:

Mit denselben Beispieldaten wie im vorherigen Beispiel, enthält die in der SAME_OWNER-Spalte ausgegebene Liste nun jeweils einen Eintrag weniger, weil der Haupt-Benutzer nun ausschließlich in der username-Spalte erscheint.

Das Ergebnis erscheint in einer CSV-Suche deutlich übersichtlicher:

username,SAME_OWNER
bbanner,[pparker, srogers, ...]
bwayne,[ckent, acurry, ...]
...

HINWEIS◄ Auch in diesem Beispiel ist erkennbar, dass die Reihenfolge der Listeneinträge innerhalb des SAME_OWNER-Felds "unsortiert" wirkt. Es besteht keine Möglichkeit auf die Reihenfolge innerhalb der Collection Einfluss zu nehmen. Auch eine Sortierung nach der einer Feldprojektion wie u2.username ist nicht hilfreich. Im Gegenteil: Die Collection Projektion liefert weiterhin unsortiert und die Sortierung multipliziert die Ausgabezeilen (Benuzter x u2) obwohl im Datenobjekt Join (u2) die Option Optional ausgewählt ist (s. o.).

   <core:TupleSearchResult maxResults="100" count="3">
<columns>
<name>username</name>
<name>SAME_OWNER</name>
</columns>
<result>
<row>
<item xsi:type="xsd:string">bbanner</item>
<item xsi:type="list">
<entry xsi:type="xsd:string">pparker</entry>
<entry xsi:type="xsd:string">srogers</entry>
...
</item>
</row>
<row>
<item xsi:type="xsd:string">bwayne</item>
<item xsi:type="list">
<entry xsi:type="xsd:string">ckent</entry>
<entry xsi:type="xsd:string">acurry</entry>
...
</item>
</row>
</result>
...
</core:TupleSearchResult>

Komplexeres Beispiel: Je Benutzer, die Kontonummern der Firmen auflisten, die beim Anmelden auswählbar sind

Eine Tupel-Suche für Benutzer soll in einer Listenspalte je Benutzer die Kontonummern aller beim Anmelden als Firma der Session auswählbaren Firmen angeben.

Konfiguration:

Die Benutzer-Suche verwendet einen Datenobjekt Join für die Entität "Firmenkonto", der unter dem Alias-Namen ca (für CompanyAccount) jedem Benutzerkonto die im Feld "Firmen" (companies) referenzierten Firmenkonten zuordnet.

images/download/attachments/155419707/image-2023-11-13_13-6-3-version-1-modificationdate-1699877168510-api-v2.png

Aus den Daten der per Datenobjekt Join zugeordneten Firmenkonten wird das Adressfeld "Kontonummer" (address.accountNumber) per Collection Projektion in eine Liste überführt:

Die rechts abgebildete Collection Projektion für die Listenspalte mit Name "CA_ACC_NUMBERS") greift über eine Feldprojektion mit dem im Parameter Feld für Join angegebenen Pfad ca.address.accNumber unmittelbar auf das "Kontonummer"-Feld jeder Firma zu, die der Datenobjekt Join (ca), dem jeweiligen Benutzerkonto zuordnet.

Die Collection zeigt mit dieser Konfiguration keine Hinweise auf Firmen, für die keine Angabe zur "Kontonummer" vorliegt.

images/download/attachments/155419707/image-2023-11-13_13-11-1-version-1-modificationdate-1699877466809-api-v2.png

Die Collection Projektion soll nun noch so angepasst werden, dass im Feld CA_ACC_NUMBERS der Text "UNIDENTIFIED_ACCOUNT" erscheint, falls einem Benutzer eine Firma ohne Kontonummer zugeordnet ist:

  • Konkret soll die "Kontonummer" als ausgefüllt gelten, wenn sie mindestens ein beliebiges Zeichen beinhaltet. Innerhalb einer Wenn ( Case ) Projektion für das Feld der Collection definiert eine Feld Einschränkung dafür die Bedingung "like _%".

  • Gilt die "Kontonummer" als ausgefüllt (linker Zweig der Fallunterscheidung), wird der Rückgabewert (wie oben bereits) direkt aus der Feldprojektion für den Pfad ca.address.accNumber weitergegeben.

  • Gilt die "Kontonummer" als nicht ausgefüllt (rechter Zweig der Fallunterscheidung), wird über eine Literale Projektion der statische Text UNIDENTIFIED_ACCOUNT als Rückgabewert zugewiesen.

images/download/attachments/155419707/image-2023-11-13_13-27-24-version-1-modificationdate-1699878450013-api-v2.png

Ausgehend von der bestehenden Konfiguration soll nun noch verhindert werden, dass die Collection in der Listenspalte CA_ACC_NUMBERS Firmenkonten berücksichtigt, in deren Konto das Feld "Metatyp" auf den Firmen-Metatyp "Gruppe" (GROUP) verweist.

  • Die "Gruppen"-Firmenkonten soll hier ausdrücklich nicht schon im Datenobjekt Join ausgefiltert werden, damit deren Daten in der Collection Projektion für eine weitere Listenspalte gesondert ausgegeben werden können.

Der folgende Screenshot zeigt einen zusätzlichen Zweig in der Wenn ( Case ) Projektion für das Feld der Collection, in dem vor allen anderen Bedingungen der "Metatyp" der Firma (ca.metaType) ausgewertet wird, um "Kein Wert" ($null) zuzuweisen, wenn der Firmen-Metatyp "Gruppe" (GROUP) vorliegt.

  • Wenn "Kein Wert" ($null) als Rückgabewert zugewiesen wird, taucht in der Collection weder eine ggf. zugeordnete "Kontonummer" noch der Hinweistext "UNIDENTIFIED_ACCOUNT" auf.

images/download/attachments/155419707/image-2023-11-13_13-45-22-version-1-modificationdate-1699879527380-api-v2.png