{"id":3498,"date":"2025-09-17T07:03:44","date_gmt":"2025-09-17T07:03:44","guid":{"rendered":"https:\/\/structr.com\/blog\/graalvm-trifft-structr-low-code-eine-polyglotte-revolution-in-der-graphenbasierten-entwicklung\/"},"modified":"2025-09-18T09:58:07","modified_gmt":"2025-09-18T09:58:07","slug":"graalvm-trifft-structr-low-code-eine-polyglotte-revolution-in-der-graphenbasierten-entwicklung","status":"publish","type":"post","link":"https:\/\/structr.com\/de\/blog\/graalvm-trifft-structr-low-code-eine-polyglotte-revolution-in-der-graphenbasierten-entwicklung\/","title":{"rendered":"GraalVM trifft Structr Low-Code &#8211; eine polyglotte Revolution in der graphenbasierten Entwicklung"},"content":{"rendered":"<div class=\"wpb-content-wrapper\"><p>[vc_row][vc_column][vc_column_text]Die Landschaft der Low-Code-Entwicklungsplattformen hat sich rasant weiterentwickelt, wobei sich Structr stets an der Spitze der Innovation im Bereich der graphbasierten Anwendungsentwicklung positioniert hat. Heute m\u00f6chten wir einen der bedeutendsten Fortschritte in der Entwicklung von Structr vorstellen: die Integration der Polyglot Engine von <a href=\"https:\/\/www.graalvm.org\/\" target=\"_blank\" rel=\"noopener\">GraalVM<\/a>, die mit Structr 4.0 eingef\u00fchrt wurde und die Art und Weise revolutioniert hat, wie Entwickler mit den leistungsstarken graphbasierten Funktionen von Structr arbeiten.<\/p>\n<p>Diese Integration f\u00fchren wir mit der bevorstehenden Ver\u00f6ffentlichung von Structr Version 6.0 fort, indem wir die Funktionen zusammen mit mehreren wichtigen Verbesserungen erweitern. Die bedeutendsten Neuerungen umfassen ein Upgrade auf GraalVM 24 sowie die umfassende Unterst\u00fctzung f\u00fcr ECMA-Script-Module, wodurch Entwickler JavaScript-Bibliotheken direkt im integrierten Dateisystem von Structr erstellen und organisieren k\u00f6nnen. Zudem erm\u00f6glicht diese Integration das nahtlose Einbinden vorhandener Codebasen und die Verwendung von Standard-ES6-Importanweisungen in der gesamten polyglotten Umgebung. Der dateisystembasierte Modulansatz geht dabei \u00fcber JavaScript hinaus und umfasst selbstverst\u00e4ndlich auch alle anderen von GraalVM unterst\u00fctzten Sprachen.<\/p>\n<p>Diese Fortschritte er\u00f6ffnen Entwicklern neue M\u00f6glichkeiten: Sie k\u00f6nnen Code in Structr-Projekten deutlich besser organisieren und wiederverwenden sowie modulare Bibliotheken erstellen, die zwischen verschiedenen Anwendungen und Komponenten innerhalb der Plattform gemeinsam genutzt werden k\u00f6nnen. Dabei bleiben die entscheidenden Vorteile der schnellen Entwicklung vollst\u00e4ndig erhalten, die die Low-Code-Entwicklung so effektiv machen.[\/vc_column_text][vc_single_image image=&#8220;3425&#8243; img_size=&#8220;medium&#8220;]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Von veralteten JavaScript-Engines zur modernen polyglotten Laufzeitumgebung<\/h2><\/div><\/div>[vc_column_text]Structr baute lange auf JavaScript-Engines wie Nashorn und Rhino auf, um seine Skriptfunktionen zu realisieren. Diese Engines leisteten in der Anfangszeit gute Dienste, wurden jedoch mit der Zeit zu einem Problem, da sie veraltet waren, nur noch eingeschr\u00e4nkten JavaScript-Support boten und unter Performanceproblemen litten, die moderne Entwicklungsworkflows hinderten.<\/p>\n<p>Die Integration der Polyglot Engine von GraalVM stellt einen grundlegenden Wandel von der Skriptintegration zu einer wirklich modernen, mehrsprachigen Entwicklungsumgebung dar. Wo Entwickler fr\u00fcher durch die Einschr\u00e4nkungen \u00e4lterer JavaScript-Engines eingeschr\u00e4nkt waren, k\u00f6nnen sie nun aus mehreren Programmiersprachen w\u00e4hlen \u2013 JavaScript mit moderner ES6+-Unterst\u00fctzung, Python und viele andere \u2013 und das alles in einer einheitlichen Laufzeitumgebung, die eine nahtlose Interoperabilit\u00e4t gew\u00e4hrleistet.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Structr's eingebaute Funktionsbibliothek: 200+ Funktionen an Ihren Fingerspitzen<\/h2><\/div><\/div>[vc_column_text]Das Herzst\u00fcck der GraalVM Integration ist die umfangreiche Funktionsbibliothek von Structr mit \u00fcber 200 integrierten Funktionen, auf die \u00fcber die Objekte <code>$<\/code> oder <code>Structr<\/code> zugegriffen werden kann. Diese Funktionen umfassen alles von komplexen Neo4j Cypher-Abfragen und HTTP-API-Integrationen bis hin zur PDF-Generierung und MongoDB-Operationen. Mit der Polyglot Engine von GraalVM steht dieses gesamte Funktions\u00f6kosystem in mehreren Programmiersprachen zur Verf\u00fcgung, was Entwicklern eine enorme Flexibilit\u00e4t bei der Umsetzung der Anwendungslogik bietet.<\/p>\n<p>Die Funktionskategorien umfassen:<\/p>\n<ul>\n<li>Datenbankoperationen: Direkte Neo4j-Integration mit <code>$.cypher()<\/code> und erweiterte Suche mit <code>$.find()<\/code><\/li>\n<li>Integration externer APIs: HTTP-Funktionen f\u00fcr nahtlose Servicekommunikation<\/li>\n<li>Dokumentenerstellung: Dateierstellung (PDF, CSV, Excel, XML usw.) und Dateibearbeitungsfunktionen<\/li>\n<li>Datenbankkonnektivit\u00e4t: Neo4j, MongoDB, JDBC-Integration und Zugriff auf externe Datenbanken<\/li>\n<li>Transaktionsmanagement: Erweiterte Transaktionsverarbeitung mit <code>$.doInNewTransaction()<\/code> oder <code>$.schedule()<\/code><\/li>\n<\/ul>\n<pre>{\r\n\t\/\/ Einfaches Beispiel: Suchen von Benutzern mit Pr\u00e4dikaten\r\n\t$.find('User', $.predicate.equals('isAdmin', true));\r\n}\r\n<\/pre>\n<p>Eine vollst\u00e4ndige Referenz aller verf\u00fcgbaren Funktionen finden Sie in der <a href=\"https:\/\/docs.structr.com\/docs\/built-in-functions\" target=\"_blank\" rel=\"noopener\">Dokumentation der eingebauten Funktionen von Structr<\/a>.<\/p>\n<p>Umfassende Beispiele f\u00fcr alle Funktionskategorien finden Sie im Abschnitt Detaillierte Funktionsbeispiele weiter unten.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Graphen-Navigation: Von komplexen Abfragen zu intuitivem Objektzugriff<\/h2><\/div><\/div>[vc_column_text]Einer der leistungsst\u00e4rksten Aspekte der GraalVM-Integration von Structr ist die Umwandlung komplexer Neo4j-Graphbeziehungen in intuitive Objektnavigation. Anstatt f\u00fcr jeden Beziehungszugriff komplexe Cypher-Abfragen zu schreiben, k\u00f6nnen Entwickler den Graphen mit einfachen Property-Access-Mustern navigieren, welche sich in jeder Programmiersprache nat\u00fcrlich anf\u00fchlen.[\/vc_column_text][vc_single_image image=&#8220;3432&#8243; img_size=&#8220;full&#8220;][vc_column_text]Ein Beispiel: In einem Project Management System mit Projects, ProjectTasks und Usern w\u00fcrde man normalerweise komplexe Cypher Queries schreiben. Mit Structr wird es so einfach wie ein normaler Objekt-Propertyzugriff:<\/p>\n<pre>{\r\n\t\/\/ Intuitive Navigation durch Graphbeziehungen\r\n\tlet user = $.me; \/\/ \u201eme\" als Keyword f\u00fcr den authentifizierten Benutzer\r\n\tlet userTasks = user.tasks; \/\/ Automatische Aufl\u00f6sung von Beziehungen\r\n\tuserTasks.map(task =&gt; task.project);\r\n}<\/pre>\n<p>Mit diesem Ansatz k\u00f6nnen Entwickler das Beste aus beiden Welten kombinieren: Cypher f\u00fcr komplexe Patternmatching und Filterung, dann JavaScript f\u00fcr die Datenverarbeitung und Gesch\u00e4ftslogik. Siehe Siehe <a href=\"https:\/\/structr.com\/de\/blog\/graalvm-trifft-structr-low-code-eine-polyglotte-revolution-in-der-graphenbasierten-entwicklung\/#example\">Beispiele f\u00fcr erweiterte Graphnavigation<\/a> f\u00fcr Multi-Hop-Durchl\u00e4ufe und komplexe Muster.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Schema-Methoden: Einbettung polyglotter Logik in Datentypen<\/h2><\/div><\/div>[vc_column_text]Die integration der Polyglot Engine von GraalVM geht \u00fcber Scripting hinaus und erstreckt sich bis in die Schemadefinition von Structr selbst. Entwickler k\u00f6nnen benutzerdefinierte Methoden direkt f\u00fcr Datentypen definieren und so wiederverwendbare Gesch\u00e4ftslogik erstellen, die im Datenmodell verankert ist. Diese Methoden k\u00f6nnen in jeder unterst\u00fctzten polyglotten Sprache implementiert werden und haben Zugriff auf die gesamte Structr-Funktionsbibliothek.<\/p>\n<p>Es gibt drei verschiedene Arten von Schema-Methoden, die jeweils unterschiedlichen Zwecken innerhalb des Datenmodells von Structr dienen:<\/p>\n<ul>\n<li>Lifecyle Methoden: Werden von Structr automatisch w\u00e4hrend Events von Knoten wie <code>onCreate<\/code>, <code>onSave<\/code>, <code>onDelete<\/code> und anderen ausgel\u00f6st. Diese Methoden werden mit Zugriff auf <code>$.this<\/code> im Kontext eines Datenbankknoten aufgerufen, wenn das entsprechende Ereignis eintritt, und erm\u00f6glichen so automatische Datenvalidierung, die Verwaltung von Beziehungen oder anderen Prozessen.<\/li>\n<li>Instanzmethoden: Werden explizit f\u00fcr bestimmte Knoteninstanzen aufgerufen, die \u00fcber <code>$.this<\/code> Zugriff auf den aktuellen Knotenkontext haben. Diese Methoden kapseln Gesch\u00e4ftslogik, die auf einzelnen Knoten ausgef\u00fchrt wird, und k\u00f6nnen die volle Leistungsf\u00e4higkeit der integrierten Funktionen von Structr nutzen.<\/li>\n<li>Statische Methoden: Werden direkt f\u00fcr Datentypen aufgerufen, ohne dass eine bestimmte Knoteninstanz erforderlich ist. Diese Hilfsmethoden eignen sich ideal f\u00fcr Operationen auf Typ-Ebene, wie das Suchen von Knoten mit bestimmten Kriterien oder das Ausf\u00fchren von Aggregatoperationen \u00fcber alle Instanzen eines Typs hinweg.<\/li>\n<\/ul>\n<pre>\/\/ Einfaches Beispiel f\u00fcr eine Schemamethode\r\n{\r\n    \/\/ Instanzmethode auf Project Typ\r\n    $.this.tasks.push($.create(\"ProjectTask\", {name: \"New Task\"}));\r\n}<\/pre>\n<p>So k\u00f6nnen Entwickler die Gesch\u00e4ftslogik direkt in ihrem Datenmodell kapseln, wodurch Anwendungen wartungsfreundlicher und die Logik wiederverwendbarer wird. _Umfassende Beispiele f\u00fcr Schema-Methoden einschlie\u00dflich Python-Implementierungen: <a href=\"https:\/\/structr.com\/de\/blog\/graalvm-trifft-structr-low-code-eine-polyglotte-revolution-in-der-graphenbasierten-entwicklung\/#example\">Beispiele f\u00fcr Schemamethoden<\/a>.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Frontend-Integration: Polyglotte Leistungsf\u00e4higkeit in Templates<\/h2><\/div><\/div>[vc_column_text]Die gleichen polyglotten F\u00e4higkeiten erstrecken sich nahtlos \u00fcber den gesamten Stack von Structr, einschlie\u00dflich des Frontend-Template-Rendering. Entwickler k\u00f6nnen die Graph-Navigation und interne Funktionen direkt in Templates verwenden und so dynamische, datengesteuerte Interfaces erstellen.<\/p>\n<pre>&lt;div class=\"user-dashboard\"&gt;\r\n    &lt;h2&gt;Meine Projekte&lt;\/h2&gt;\r\n    &lt;div class=\"projects-container\"&gt;\r\n        ${{\r\n            let userProjects = $.mergeUnique($.me.tasks.map(task =&gt; task.project));\r\n            $.include(\"project-list-template\", userProjects, \"project\");\r\n        }}\r\n    &lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<\/pre>\n<p>Das zeigt die globale Integration der Polyglot Engine von GraalVM \u2013 egal, ob man sich in der Backend-Logik, im Frontend-Rendering oder in Schema-Methoden befindet, die gleichen Navigationsmuster und Funktionen verhalten sich konsistent in allen Kontexten.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Mehrsprachige Unterst\u00fctzung: \u00dcber JavaScript hinaus<\/h2><\/div><\/div>[vc_column_text]W\u00e4hrend JavaScript weiterhin die prim\u00e4re Skriptsprache in Structr bleibt, \u00f6ffnet die Polyglot Engine von GraalVM die T\u00fcren f\u00fcr zus\u00e4tzliche Programmiersprachen f\u00fcr spezielle Anwendungsf\u00e4lle. Python bietet beispielsweise leistungsstarke Datenverarbeitungsfunktionen und andere Sprachen k\u00f6nnen ebenfalls bei Bedarf integriert werden.<\/p>\n<pre>python{ \r\ndef getUserNames(): \r\n\tusers = list(map(lambda u: u.name, Structr.find(\"User\"))) \r\n\treturn users \r\n\r\ngetUserNames() \r\n}<\/pre>\n<p>Das Besondere an diesem Ansatz ist, dass Entwickler unabh\u00e4ngig von der gew\u00e4hlten Sprache \u00fcber konsistente APIs wie <code>Structr.find()<\/code> f\u00fcr Python-Kontexte Zugriff auf die umfassende integrierte Funktionsbibliothek von Structr behalten.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Fazit: Eine neue \u00c4ra der Low-Code-Entwicklung<\/h2><\/div><\/div>[vc_column_text]Die Integration von GraalVM in Structr ist mehr als nur ein technisches Upgrade \u2013 es ist ein Paradigmenwechsel, der moderne, polyglotte Funktionen in die graphbasierte Low-Code-Entwicklung bringt. Durch die Kombination von intuitiver Objektnavigation, der Flexibilit\u00e4t mehrerer Programmiersprachen und der umfassenden Funktionalit\u00e4t der integrierten Bibliothek von Structr k\u00f6nnen Entwickler anspruchsvolle Anwendungen mit beispielloser Leichtigkeit und Flexibilit\u00e4t erstellen.<\/p>\n<p>Diese Transformation sorgt daf\u00fcr, dass Structr an der Spitze von Low-Code-Plattformen bleibt und Entwicklern die Tools zur Verf\u00fcgung stellt, die sie ben\u00f6tigen, um komplexe Herausforderungen zu bew\u00e4ltigen und gleichzeitig die schnellen Entwicklungsf\u00e4higkeiten beizubehalten, die Low-Code-Plattformen so leistungsstark machen.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \"  id=\"examples\" >Detaillierte Funktionsbeispiele<\/h2><\/div><\/div><div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Datenbankoperationen mit JavaScript<\/h3><\/div><\/div>[vc_column_text]Eines der leistungsst\u00e4rksten Features von Structr ist die direkte Integration mit Neo4j \u00fcber integrierte Funktionen wie <code>$.cypher()<\/code> und <code>$.find()<\/code>. Diese Datenbankoperationen bieten intuitiven Zugriff auf komplexe Graphabfragen und Datenmanipulation.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Komplexe Benutzerabfrage<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\t\/\/ Admin-Benutzer mit erweiterten Pr\u00e4dikaten suchen\r\n\t\/\/ In diesem Beispiel nur Users mit den Namen \"jeff\" oder \"joe\" finden\r\n\tlet adminUsers = $.find('User', $.predicate.and(\r\n\t    $.predicate.equals('isAdmin', true),\r\n\t    $.predicate.or([\r\n\t        $.predicate.equals('name', 'jeff'),\r\n\t        $.predicate.equals('name', 'joe')\r\n\t    ])\r\n\t));\r\n\t\r\n\t\/\/ Raw Cypher mit Parametern ausf\u00fchren\r\n\tlet query = \"MATCH (user:User) WHERE user.name = $userName RETURN user\";\r\n\tlet users = $.cypher(query, {userName: 'admin'});\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Erweiterte Transaktionsverwaltung<\/h3><\/div><\/div>[vc_column_text]Die Funktion <code>$.doInNewTransaction()<\/code> von Structr zeigt, wie komplexe Datenbankoperationen mit geeigneten Transaktionsgrenzen verwaltet werden k\u00f6nnen:[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Stapelverarbeitung<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\tlet pageSize = 10;\r\n\tlet pageNo = 1;\r\n\t\r\n\t$.doInNewTransaction(function() {\r\n\t    let nodes = $.find('User', $.predicate.page(pageNo, pageSize));\r\n\t    \r\n\t    nodes.forEach(user =&gt; {\r\n\t        $.set(user, {lastProcessed: new Date()});\r\n\t    });\r\n\t    \r\n\t    pageNo++;\r\n\t    return (nodes.length &gt; 0);\r\n\t}, function(error) {\r\n\t    $.log('Fehler aufgetreten:', error.getMessage());\r\n\t    return false;\r\n\t});\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Externe API-Integration<\/h3><\/div><\/div>[vc_column_text]Die HTTP-Funktionen von Structr zeigen, wie die Integration externer Dienste nahtlos funktioniert.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >RESTful API-Aufrufe<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n        \/\/ Header konfigurieren und Anfragen stellen\r\n        $.addHeader('Authorization', 'Bearer ' + token);\r\n\t$.addHeader('Content-Type', 'application\/json');\r\n\t\r\n\t\/\/ Einfaches GET-Request-Beispiel\r\n\tlet response = $.GET('https:\/\/api.example.com\/users');\r\n\t\r\n\t\/\/ POST-Request-Beispiel\r\n\tlet postData = JSON.stringify({\r\n            name: 'New User',\r\n            email: 'user@example.com'\r\n\t});\r\n\t\r\n\tlet createResponse = $.POST('https:\/\/api.example.com\/users', postData);\r\n\t\r\n\tif (createResponse.status === 201) {\r\n\t    let newUser = createResponse.body;\r\n\t    $.log('Benutzer erstellt:', newUser.id);\r\n\t}\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >MongoDB-Integration<\/h3><\/div><\/div>[vc_column_text]Die Funktion <code>$.mongodb()<\/code> zeigt, wie externe Datenbankverbindungen nahtlos funktionieren.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >MongoDB-Betrieb<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\tlet collection = $.mongodb('mongodb:\/\/localhost', 'testDatabase', 'testCollection');\r\n\t\r\n\t\/\/ Mit BSON-Helper einf\u00fcgen\r\n\tcollection.insertOne($.bson({\r\n\t    name: 'Test User',\r\n\t    email: 'test@example.com',\r\n\t    created: new Date()\r\n\t}));\r\n\t\r\n\t\/\/ Komplexe Abfragen\r\n\tlet activeAdmins = collection.find($.bson({\r\n\t    $and: [\r\n\t        { active: true },\r\n\t        { role: 'admin' },\r\n\t        { lastLogin: { $gte: new Date(2023, 0, 1) } }\r\n\t    ]\r\n\t}));\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Dokumentenerstellung und Dateioperationen<\/h3><\/div><\/div>[vc_column_text]Die Funktionen von Structr zur Dokumentenerstellung, wie beispielsweise die PDF-Erstellung, bieten leistungsstarke Tools zur Inhaltserstellung:[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >PDF-Generation<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\t$.setResponseHeader('Content-Disposition', 'attachment; filename=\"report.pdf\"');\r\n\t$.setResponseHeader('Cache-Control', 'no-cache');\r\n\t\r\n\tlet mainPage = 'pdf-export-main-page\/';\r\n\tlet header = '--header-html ' + $.get('base_url') + '\/pdf-export-header-page\/';\r\n\tlet footer = '--footer-html ' + $.get('base_url') + '\/pdf-export-footer-page\/';\r\n\tlet wkhtmlArgs = header + ' ' + footer + ' --disable-smart-shrinking';\r\n\t\r\n\t\/\/ HTML-Seiten in PDF umwandeln\r\n\tlet pdf = $.pdf(mainPage, wkhtmlArgs);\r\n\t\r\n\t\/\/ PDF-Inhalt in einer neuen Datei speichern\r\n\tlet newPDFFile = $.create(\"File\", {\r\n\t\tname: 'new-file.pdf'\r\n\t})\r\n\t$.setContent(newPDFFile, pdf, \"ISO-8859-1\");\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Beispiele f\u00fcr erweiterte Graphnavigation<\/h2><\/div><\/div><div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >JavaScript-Grafik-Navigation<\/h3><\/div><\/div>[vc_column_text]Mit der polyglotten Engine von Structr wird die Navigation in Beziehungen so einfach wie der Zugriff auf Objekteigenschaften:[\/vc_column_text][vc_column_text]<\/p>\n<pre>{\r\n\t\/\/ Aktuellen authentifizierten Benutzer abrufen\r\n\tlet user = $.me;\r\n\t\r\n\t\/\/ Direkt zu allen diesem Benutzer zugewiesenen Aufgaben navigieren\r\n\t\/\/ Dies durchl\u00e4uft automatisch die WORKS_ON-Beziehung\r\n\tlet allUserTasks = user.tasks;\r\n\t\r\n\t\/\/ Von Aufgaben zu ihren \u00fcbergeordneten Projekten navigieren\r\n\t\/\/ Reduce verwenden, um eindeutige Projekte aus allen Aufgaben zu sammeln\r\n\tlet allProjectsOfUser = $.mergeUnique(user.tasks.map(task =&gt; task.project));\r\n\t\r\n\t\/\/ Aufgabenanzahl pro Projekt f\u00fcr den aktuellen Benutzer abrufen\r\n\tlet projectTaskCounts = allProjectsOfUser.map(project =&gt; ({\r\n\t    project: project,\r\n\t    taskCount: project.tasks.filter(task =&gt; user.tasks.includes(task)).length,\r\n\t    completedTasks: project.tasks.filter(task =&gt; \r\n\t        user.tasks.includes(task) &amp;&amp; task.completed\r\n\t    ).length\r\n\t}));\r\n\t\r\n\t\/\/ Projekte finden, bei denen der Benutzer der Hauptmitwirkende ist\r\n\tlet primaryProjects = allProjectsOfUser.filter(project =&gt; {\r\n\t    let projectTasks = project.tasks;\r\n\t    let userTasksInProject = projectTasks.filter(task =&gt; user.tasks.includes(task));\r\n\t    return userTasksInProject.length &gt; projectTasks.length * 0.5; \/\/ &gt;50% der Aufgaben\r\n\t});\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Multi-Hop-Navigation<\/h3><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\t\/\/ Navigation durch mehrere Beziehungsebenen\r\n\tlet user = $.me;\r\n\t\r\n\t\/\/ Alle Teammitglieder abrufen, die an denselben Projekten arbeiten\r\n\tlet userProjects = user.tasks.map(task =&gt; task.project);\r\n\tlet colleagues = [];\r\n\t\r\n\tfor (let project of userProjects) {\r\n\t    let projectUsers = project.tasks\r\n\t        .flatMap(task =&gt; task.users)\r\n\t        .filter(colleague =&gt; colleague.id !== user.id);\r\n\t    \r\n\t    \/\/ Eindeutige Kollegen hinzuf\u00fcgen\r\n\t    for (let colleague of projectUsers) {\r\n\t        if (!colleagues.find(c =&gt; c.id === colleague.id)) {\r\n\t            colleagues.push(colleague);\r\n\t        }\r\n\t    }\r\n\t}\r\n\t\r\n\t\/\/ Projektabh\u00e4ngigkeiten durch geteilte Ressourcen finden\r\n\tlet projectDependencies = userProjects.map(project =&gt; {\r\n\t    let dependencies = [];\r\n\t    \r\n\t    \/\/ Alle Benutzer abrufen, die an diesem Projekt arbeiten\r\n\t    let projectUsers = project.tasks.reduce((users, task) =&gt; {\r\n\t        task.users.forEach(user =&gt; {\r\n\t            if (!users.find(u =&gt; u.id === user.id)) {\r\n\t                users.push(user);\r\n\t            }\r\n\t        });\r\n\t        return users;\r\n\t    }, []);\r\n\t    \r\n\t    \/\/ Andere Projekte finden, an denen diese Benutzer arbeiten\r\n\t    for (let projectUser of projectUsers) {\r\n\t        let otherProjects = projectUser.tasks\r\n\t            .map(task =&gt; task.project)\r\n\t            .filter(p =&gt; p.id !== project.id);\r\n\t            \r\n\t        for (let otherProject of otherProjects) {\r\n\t            if (!dependencies.find(p =&gt; p.id === otherProject.id)) {\r\n\t                dependencies.push(otherProject);\r\n\t            }\r\n\t        }\r\n\t    }\r\n\t    \r\n\t    return {\r\n\t        project: project,\r\n\t        dependencies: dependencies\r\n\t    };\r\n\t});\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Mischen von Graph-Navigation mit Cypher<\/h3><\/div><\/div>[vc_column_text]<\/p>\n<pre>{\r\n\tlet user = $.me;\r\n\t\r\n\t\/\/ Graph-Navigation f\u00fcr einfache Beziehungstraversierung verwenden\r\n\tlet projectTimeline = user.tasks.map(task =&gt; ({\r\n\t    project: task.project.name,\r\n\t    task: task.name,\r\n\t    startDate: task.startDate,\r\n\t    endDate: task.endDate,\r\n\t    status: task.status,\r\n\t    teamSize: task.users.length\r\n\t}));\r\n\t\r\n\t\/\/ Nach Startdatum sortieren\r\n\tprojectTimeline.sort((a, b) =&gt; a.startDate - b.startDate);\r\n\t\r\n\t\/\/ Cypher f\u00fcr komplexe Filterung und Mustersuche verwenden\r\n\tlet qualityQuery = `\r\n\t    MATCH (u:User {id: $userId})-[:WORKS_ON]-&gt;(task:ProjectTask)&lt;-[:HAS]-(project:Project)\r\n\t    WHERE project.status = 'active' \r\n\t      AND task.priority IN ['high', 'critical']\r\n\t      AND task.dueDate &gt; timestamp()\r\n\t    RETURN DISTINCT project\r\n\t`;\r\n\t\r\n\tlet activeHighPriorityProjects = $.cypher(qualityQuery, {userId: user.id});\r\n\t\r\n\t\/\/ Jetzt Structr's JavaScript-Funktionen f\u00fcr Qualit\u00e4tsanalyse verwenden\r\n\tlet qualityAnalysis = activeHighPriorityProjects.map(project =&gt; {\r\n\t    \/\/ Alle Aufgaben in diesem Projekt mit Graph-Navigation abrufen\r\n\t    let allProjectTasks = project.tasks;\r\n\t    let userTasks = user.tasks.filter(task =&gt; task.project.id === project.id);\r\n\t    \r\n\t    \/\/ Qualit\u00e4tsmetriken mit JavaScript berechnen\r\n\t    let overdueTasks = allProjectTasks.filter(task =&gt; \r\n\t        task.dueDate &amp;&amp; task.dueDate &lt; Date.now() &amp;&amp; task.status !== 'completed'\r\n\t    ).length;\r\n\t    \r\n\t    let completionRate = allProjectTasks.length &gt; 0 \r\n\t        ? (allProjectTasks.filter(task =&gt; task.status === 'completed').length \/ allProjectTasks.length * 100).toFixed(1)\r\n\t        : 0;\r\n\t    \r\n\t    \/\/ Kritische Pfad-Aufgaben mit Graph-Navigation finden\r\n\t    let criticalTasks = allProjectTasks.filter(task =&gt; \r\n\t        task.priority === 'critical' &amp;&amp; task.status !== 'completed'\r\n\t    );\r\n\t    \r\n\t    \/\/ Team-Geschwindigkeit berechnen\r\n\t    let recentlyCompleted = allProjectTasks.filter(task =&gt; \r\n\t        task.status === 'completed' &amp;&amp; \r\n\t        task.completedDate &amp;&amp; \r\n\t        task.completedDate &gt; Date.now() - (7 * 24 * 60 * 60 * 1000) \/\/ Letzte 7 Tage\r\n\t    ).length;\r\n\t    \r\n\t    return {\r\n\t        projectName: project.name,\r\n\t        projectDeadline: project.deadline,\r\n\t        totalTasks: allProjectTasks.length,\r\n\t        userTasks: userTasks.length,\r\n\t        overdueTasks: overdueTasks,\r\n\t        completionRate: completionRate,\r\n\t        criticalTasksRemaining: criticalTasks.length,\r\n\t        weeklyVelocity: recentlyCompleted,\r\n\t        riskLevel: overdueTasks &gt; 3 || criticalTasks.length &gt; 1 ? 'high' : 'low'\r\n\t    };\r\n\t});\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h2 \"><h2 class=\"heading   \" >Beispiele f\u00fcr Schema-Methoden<\/h2><\/div><\/div><div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Instanzmethoden auf Datentypen<\/h3><\/div><\/div>[vc_column_text]Schemamethoden k\u00f6nnen f\u00fcr jeden Datentyp definiert und direkt auf Knoteninstanzen aufgerufen werden, die \u00fcber Funktionen wie <code>$.cypher()<\/code> oder <code>$.find()<\/code> abgerufen werden. Diese Methoden haben \u00fcber <code>$.this<\/code> Zugriff auf den aktuellen Knotenkontext und k\u00f6nnen die volle Leistungsf\u00e4higkeit der eingebauten Funktionen von Structr nutzen.[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Beispiel - Projekttyp mit addNewTask-Methode<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>\/\/ Methode definiert auf Project-Schema-Typ\r\n{\r\n    \/\/ F\u00fcgt eine neue ProjectTask hinzu und verbindet sie mit dem Projektknoten\r\n    $.this.tasks.push($.create(\"ProjectTask\", {\r\n        name: $.methodsParameters.name ?? \"New Task\", \r\n        dueDate: new Date(2026, 01, 01)\r\n    }));\r\n}<\/pre>\n<p>[\/vc_column_text][vc_column_text]<\/p>\n<pre>{\r\n\t\/\/ Ein Projekt finden und die benutzerdefinierte Methode aufrufen\r\n\tlet project = $.find('Project', {name: 'Website Redesign'})[0];\r\n\tproject.addNewTask({name: `New Task for ${project.name}`}); \/\/ Ruft die Schema-Methode auf\r\n\t\r\n\t\/\/ Oder mit Cypher-Ergebnissen verwenden\r\n\tlet urgentProjects = $.cypher('MATCH (p:Project) WHERE p.priority = \"urgent\" RETURN p');\r\n\turgentProjects.forEach(project =&gt; {\r\n\t    project.addNewTask({name: `New Task for ${project.id}`}); \/\/ Jedes Projekt erh\u00e4lt eine neue Aufgabe\r\n\t});\r\n}\r\n<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Beispiele f\u00fcr erweiterte Schemamethoden<\/h3><\/div><\/div><div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Projekttyp - Projektstatus berechnen<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>\/\/ Schema-Methode: calculateHealth()\r\n{\r\n    let totalTasks = $.this.tasks.length;\r\n    let completedTasks = $.this.tasks.filter(task =&gt; task.status === 'completed').length;\r\n    let overdueTasks = $.this.tasks.filter(task =&gt; \r\n        task.dueDate &amp;&amp; task.dueDate &lt; Date.now() &amp;&amp; task.status !== 'completed'\r\n    ).length;\r\n    \r\n    let completionRate = totalTasks &gt; 0 ? (completedTasks \/ totalTasks) : 0;\r\n    let healthScore = Math.max(0, completionRate * 100 - (overdueTasks * 10));\r\n    \r\n    return {\r\n        healthScore: healthScore.toFixed(1),\r\n        status: healthScore &gt; 80 ? 'excellent' : healthScore &gt; 60 ? 'good' : 'needs attention',\r\n        totalTasks: totalTasks,\r\n        completedTasks: completedTasks,\r\n        overdueTasks: overdueTasks\r\n    };\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Benutzertyp \u2013 Benutzer-Arbeitsbelastung abrufen<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>\/\/ Schema-Methode: getWorkloadSummary()\r\n{\r\n    let activeTasks = $.this.tasks.filter(task =&gt; task.status !== 'completed');\r\n    let projectMap = {};\r\n    \r\n    activeTasks.forEach(task =&gt; {\r\n        let projectName = task.project.name;\r\n        if (!projectMap[projectName]) {\r\n            projectMap[projectName] = {\r\n                project: task.project,\r\n                taskCount: 0,\r\n                highPriorityCount: 0\r\n            };\r\n        }\r\n        projectMap[projectName].taskCount++;\r\n        if (task.priority === 'high' || task.priority === 'critical') {\r\n            projectMap[projectName].highPriorityCount++;\r\n        }\r\n    });\r\n    \r\n    return {\r\n        totalActiveTasks: activeTasks.length,\r\n        projectCount: Object.keys(projectMap).length,\r\n        projectBreakdown: Object.values(projectMap)\r\n    };\r\n}<\/pre>\n<p>[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h3 \"><h3 class=\"heading   \" >Statische Methoden auf Datentypen<\/h3><\/div><\/div>[vc_column_text]Statische Methoden k\u00f6nnen definiert werden, die keine bestimmte Knoteninstanz erfordern und direkt auf dem Typ aufgerufen werden k\u00f6nnen:[\/vc_column_text]<div class=\"wpb_content_element\" ><div class=\"heading heading--h4 \"><h4 class=\"heading   \" >Projekttyp - Statische Methode zum Auffinden \u00fcberf\u00e4lliger Projekte<\/h4><\/div><\/div>[vc_column_text]<\/p>\n<pre>\/\/ Statische Schema-Methode: Project.findOverdueProjects()\r\n{\r\n    let currentDate = Date.now();\r\n    return $.find('Project', {\r\n        deadline: $.predicate.lt(currentDate),\r\n        status: $.predicate.not('completed')\r\n    });\r\n}<\/pre>\n<p>[\/vc_column_text][vc_column_text]<\/p>\n<pre>{\r\n\t\/\/ Statische Methode direkt auf dem Typ aufrufen\r\n\tlet overdueProjects = $.Project.findOverdueProjects();\r\n\t\r\n\t\/\/ Ergebnisse mit zus\u00e4tzlicher Logik verarbeiten\r\n\toverdueProjects.forEach(project =&gt; {\r\n\t    let health = project.calculateHealth(); \/\/ Instanzmethode\r\n\t    if (health.healthScore &lt; 50) {\r\n\t        \/\/ Benachrichtigung senden oder Ma\u00dfnahme ergreifen\r\n\t        $.log(`Projekt ${project.name} ben\u00f6tigt sofortige Aufmerksamkeit`);\r\n\t    }\r\n\t});\r\n}\r\n<\/pre>\n<p>[\/vc_column_text][\/vc_column][\/vc_row]<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>[vc_row][vc_column][vc_column_text]Die Landschaft der Low-Code-Entwicklungsplattformen hat sich rasant weiterentwickelt, wobei sich Structr stets an der Spitze der Innovation im Bereich der \u2026<\/p>\n","protected":false},"author":5,"featured_media":3518,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[543,521,562,824,612],"tags":[],"class_list":["post-3498","post","type-post","status-publish","format-standard","hentry","category-structr-de","category-beispiel","category-cypher","category-low-code","category-programmierung"],"acf":[],"_links":{"self":[{"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/posts\/3498","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/comments?post=3498"}],"version-history":[{"count":13,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/posts\/3498\/revisions"}],"predecessor-version":[{"id":3519,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/posts\/3498\/revisions\/3519"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/media\/3518"}],"wp:attachment":[{"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/media?parent=3498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/categories?post=3498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/structr.com\/de\/wp-json\/wp\/v2\/tags?post=3498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}