From dfbabe6e5816829438e0d5149a87a9be1ab9e717 Mon Sep 17 00:00:00 2001 From: "Hofstetter Benjamin (extern)" Date: Tue, 12 Nov 2024 19:21:13 +0100 Subject: [PATCH] close #30 --- doc/06_aggregate/aggregate_debug.sparqlbook | 32 ++ .../graph/aggregate/aggregate.service.ts | 275 +++--------------- .../composition/composition-to-node-link.ts | 1 - .../graph/aggregate/model/path-definition.ts | 2 +- ...on-to-composition-links-for-class.query.ts | 141 +++++++++ ...mposition-to-node-links-for-class.query.ts | 134 +++++++++ .../neptune-full-text-search.class.ts | 6 - projects/blueprint/src/config.json | 2 +- 8 files changed, 351 insertions(+), 242 deletions(-) create mode 100644 doc/06_aggregate/aggregate_debug.sparqlbook create mode 100644 projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-composition-links-for-class.query.ts create mode 100644 projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-node-links-for-class.query.ts diff --git a/doc/06_aggregate/aggregate_debug.sparqlbook b/doc/06_aggregate/aggregate_debug.sparqlbook new file mode 100644 index 0000000..8e5b2f2 --- /dev/null +++ b/doc/06_aggregate/aggregate_debug.sparqlbook @@ -0,0 +1,32 @@ +[ + { + "kind": 2, + "language": "sparql", + "value": "# [endpoint=https://test.lindas.admin.ch/query]\n \n\nPREFIX rdf: \n PREFIX rdfs: \n PREFIX blueprint: \n\n CONSTRUCT {\n blueprint:result .\n a blueprint:CompositionLinkResult .\n blueprint:result ?result .\n rdfs:label \"Publisher\" .\n ?result ?resultP ?resultO .\n ?element_1 ?connectionPointP ?connectionPointO .\n ?result blueprint:target ?element_1 .\n \n } WHERE {\n {\n # first path element - form link\n a .\n ^/ ?result .\n ?result a .\n \n VALUES ?resultP {\n rdf:type\n rdfs:label\n }\n ?result ?resultP ?resultO .\n \n }\n }", + "metadata": {} + }, + { + "kind": 2, + "language": "sparql", + "value": "# [endpoint=https://test.lindas.admin.ch/query]\n\n PREFIX rdf: \n PREFIX rdfs: \n PREFIX blueprint: \n\n CONSTRUCT {\n blueprint:result .\n a blueprint:CompositionLinkResult .\n blueprint:result ?result .\n rdfs:label \"Publsied by\" .\n ?result ?resultP ?resultO .\n ?element_0_0 ?connectionPointP ?connectionPointO .\n ?result blueprint:source ?element_0_0 . \n } WHERE {\n \n a .\n ^/ ?element_0_1 .\n ?element_0_1 a .\n \n }", + "metadata": {} + }, + { + "kind": 2, + "language": "sparql", + "value": "PREFIX sh: \nPREFIX rdf: \nPREFIX rdfs: \nPREFIX bp: \nPREFIX data: \nPREFIX oci: \nPREFIX k8s: \n\nCONSTRUCT {\n ?shape sh:group ?aggregate .\n ?shape sh:targetClass ?type .\n\n ?outgoingLinks ?linkP ?linkO .\n ?propertyShape ?propertyP ?propertyO .\n ?path sh:inversePath ?inversePath .\n\n ?inShape sh:group ?inAggregate .\n ?inShape sh:targetClass ?type.\n\n ?incomingLinks ?linkP ?linkO .\n \n} \nWHERE {\n {\n # outgoing links\n {\n SELECT ?outgoingLinks ?aggregate ?shape ?type WHERE {\n BIND (k8s:Deployment AS ?type)\n ?shape sh:targetClass ?type .\n ?shape sh:group ?aggregate . \n ?aggregate rdf:type/rdfs:subClassOf* bp:Aggregate.\n ?outgoingLinks sh:targetClass ?aggregate .\n ?outgoingLinks a bp:AggregateLink .\n }\n }\n VALUES ?linkP { \n sh:targetClass\n sh:property\n bp:target\n rdfs:label\n }\n ?outgoingLinks ?linkP ?linkO .\n } UNION {\n # outgoing links sh:property\n {\n SELECT ?outgoingLinks WHERE {\n BIND (k8s:Deployment AS ?type)\n ?shape sh:targetClass ?type .\n ?shape sh:group ?aggregate . \n ?aggregate rdf:type/rdfs:subClassOf* bp:Aggregate.\n ?outgoingLinks sh:targetClass ?aggregate .\n ?outgoingLinks a bp:AggregateLink .\n }\n }\n \n ?outgoingLinks sh:property ?propertyShape . \n\n VALUES ?propertyP { \n sh:targetClass\n sh:path\n sh:class\n sh:name\n }\n ?propertyShape ?propertyP ?propertyO .\n OPTIONAL {\n ?propertyShape sh:path ?path .\n ?path sh:inversePath ?inversePath .\n\n }\n } UNION {\n # incoming links\n {\n SELECT ?incomingLinks ?inAggregate ?inShape ?type WHERE {\n BIND (k8s:Deployment AS ?type)\n ?inShape sh:targetClass ?type .\n ?inShape sh:group ?inAggregate . \n ?inAggregate rdf:type/rdfs:subClassOf* bp:Aggregate.\n ?incomingLinks bp:target ?inAggregate .\n ?incomingLinks a bp:AggregateLink .\n }\n }\n VALUES ?linkP { \n sh:targetClass\n sh:property\n bp:target\n rdfs:label\n }\n ?incomingLinks ?linkP ?linkO .\n } UNION {\n # incoming links sh:property\n {\n SELECT ?incomingLinks WHERE {\n BIND (k8s:Deployment AS ?type)\n ?shape sh:targetClass ?type .\n ?shape sh:group ?aggregate . \n ?aggregate rdf:type/rdfs:subClassOf* bp:Aggregate.\n ?incomingLinks bp:target ?aggregate .\n ?incomingLinks a bp:AggregateLink .\n }\n }\n ?incomingLinks sh:property ?propertyShape .\n VALUES ?propertyP { \n sh:targetClass\n sh:path\n sh:class\n sh:name\n }\n ?propertyShape ?propertyP ?propertyO .\n OPTIONAL {\n ?propertyShape sh:path ?path .\n ?path sh:inversePath ?inversePath .\n\n }\n }\n}\n\n\n\n", + "metadata": {} + }, + { + "kind": 1, + "language": "markdown", + "value": "# Bidiractional Link with Two Connectors\n", + "metadata": {} + }, + { + "kind": 2, + "language": "sparql", + "value": "\n PREFIX rdf: \n PREFIX rdfs: \n PREFIX blueprint: \n \n CONSTRUCT {\n blueprint:result .\n a blueprint:CompositionLinkResult .\n blueprint:result ?result .\n rdfs:label \"Sotred Business Objects\" .\n ?result ?resultP ?resultO .\n ?element_0_2 ?connectionPointP ?connectionPointO .\n ?element_0_2 a blueprint:ConnectionPoint .\n ?result blueprint:source ?element_0_2 . \n ?element_0_2 blueprint:target ?element_0_3 . \n ?element_0_3 ?connectionPointP ?connectionPointODest .\n ?element_0_3 a blueprint:ConnectionPoint .\n } WHERE {\n \n a .\n ?element_0_1 .\n \n\n ?element_0_1 ?element_0_2 .\n ?element_0_2 a .\n VALUES ?connectionPointP {\n rdfs:label\n rdf:type\n }\n ?element_0_2 ?connectionPointP ?connectionPointO .\n \n\n ?element_0_2 ^ ?element_0_3 .\n ?element_0_3 a .\n ?element_0_3 ?connectionPointP ?connectionPointODest .\n \n\n ?element_0_3 ^ ?result .\n ?result a .\n VALUES ?resultP {\n rdf:type\n rdfs:label\n }\n ?result ?resultP ?resultO .\n \n }", + "metadata": {} + } +] \ No newline at end of file diff --git a/projects/blueprint/src/app/core/service/graph/aggregate/aggregate.service.ts b/projects/blueprint/src/app/core/service/graph/aggregate/aggregate.service.ts index 1ce3281..35c8892 100644 --- a/projects/blueprint/src/app/core/service/graph/aggregate/aggregate.service.ts +++ b/projects/blueprint/src/app/core/service/graph/aggregate/aggregate.service.ts @@ -6,6 +6,8 @@ import { CompositionToNodeLink, ICompositionToNodeLink } from './model/compositi import { CompositionToCompositionLink, ICompositionToCompositionLink } from './model/composition/composition-to-composition-link'; import { OutgoingCompositionToNodeLinkFactory } from './factory/composition-to-node-link-factory/outgoing-composition-to-node-link-factory'; import { IncomingCompositionToNodeLinkFactory } from './factory/composition-to-node-link-factory/incoming-composition-to-node-link-factory'; +import { compositionToNodeLinksForClassQuery } from './query/composition-to-node-links-for-class.query'; +import { compositionToCompositionLinksForClassQuery } from './query/composition-to-composition-links-for-class.query'; @Injectable({ providedIn: 'root' }) @@ -382,7 +384,6 @@ export class AggregateService { private _createQueryForRootOfSourceAggregate(link: ICompositionToNodeLink, subject: string): string[] { const linkTargetNodeClass = link.targetNodeIri; const linkSourceComposition = link.sourceComposition; - if (linkSourceComposition === null) { console.warn('No source composition'); return []; @@ -416,7 +417,7 @@ export class AggregateService { const path = [...pathFromRoot, ...linkPath]; const body = path.map((pathElement, index) => { - if (index === pathFromRoot.length - 1) { + if (index === pathFromRoot.length - 1 && pathFromRoot.length != 0) { if (index === 0) { return ` <${subject}> a <${pathElement.sourceClassIri}> . @@ -442,6 +443,23 @@ export class AggregateService { } if (index === 0) { + if (pathFromRoot.length === 0) { + return ` + # first path element - form link + <${subject}> a <${pathElement.sourceClassIri}> . + <${subject}> ${pathElement.path} ?result . + ?result a <${pathElement.targetClassIri}> . + + VALUES ?resultP { + ${rdf.typePrefixed} + ${rdfs.labelPrefixed} + } + ?result ?resultP ?resultO . + BIND(?result as ?connectionPointO) + BIND(?result as ?element_0_0) + + `; + } return ` <${subject}> a <${pathElement.sourceClassIri}> . <${subject}> ${pathElement.path} ?element_${outerIndex}_${index + 1} . @@ -510,9 +528,12 @@ export class AggregateService { const pathToRoot = connectionPoint.pathToRoot; const pathToTarget = [...path, ...pathToRoot]; + const body = pathToTarget.map((pathElement, index) => { + console.log('path to root', pathToRoot.length); + console.log('body count', (pathToTarget.length - pathToRoot.length) - 1); if (index === ((pathToTarget.length - pathToRoot.length) - 1)) { - if (index === (pathToTarget.length - 1)) { + if (index === (pathToTarget.length - 1) && pathToRoot.length != 0) { return ` # connector last ?element_${outerIndex}_${index} ${pathElement.path} ?result . @@ -525,6 +546,23 @@ export class AggregateService { `; } else if (index === 0) { + if (pathToRoot.length === 0) { + return ` + # first path element - form link + <${subject}> a <${pathElement.sourceClassIri}> . + <${subject}> ${pathElement.path} ?result . + ?result a <${pathElement.targetClassIri}> . + + VALUES ?resultP { + ${rdf.typePrefixed} + ${rdfs.labelPrefixed} + } + ?result ?resultP ?resultO . + BIND(?result as ?connectionPointO) + BIND(?result as ?element_1) + + `; + } console.log('pathElement connector is first'); console.log('pathElement', index); return ` @@ -600,6 +638,7 @@ export class AggregateService { ${body} } }`; + console.log('%cquery', 'color: red', query); return [query]; }); @@ -710,234 +749,4 @@ export class AggregateService { } -// sparql template functions -function compositionToCompositionLinksForClassQuery(type: string): string { - const query = ` - ${shacl.sparqlPrefix()} - ${blueprint.sparqlPrefix()} - ${rdfs.sparqlPrefix()} - ${rdf.sparqlPrefix()} - - CONSTRUCT { - ?shape ${shacl.groupPrefixed} ?aggregate . - ?shape ${shacl.targetClassPrefixed} ?type . - - ?outgoingLinks ?linkP ?linkO . - ?propertyShape ?propertyP ?propertyO . - ?path ${shacl.inversePathPrefixed} ?inversePath . - - ?inShape ${shacl.groupPrefixed} ?inAggregate . - ?inShape ${shacl.targetClassPrefixed} ?type. - - ?incomingLinks ?linkP ?linkO . - ?incomingLinks ${rdfs.labelPrefixed} ?inverseLabel . - - } - WHERE { - { - # outgoing links - { - SELECT ?outgoingLinks ?aggregate ?shape ?type WHERE { - BIND (<${type}> AS ?type) - ?shape ${shacl.targetClassPrefixed} ?type . - ?shape ${shacl.groupPrefixed} ?aggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . - ?outgoingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . - } - } - VALUES ?linkP { - ${shacl.targetClassPrefixed} - ${shacl.propertyPrefixed} - ${blueprint.targetPrefixed} - ${rdfs.labelPrefixed} - ${rdf.typePrefixed} - } - ?outgoingLinks ?linkP ?linkO . - } UNION { - # outgoing links sh:property - { - SELECT ?outgoingLinks WHERE { - BIND (<${type}> AS ?type) - ?shape ${shacl.targetClassPrefixed} ?type . - ?shape ${shacl.groupPrefixed} ?aggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . - ?outgoingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . - } - } - - ?outgoingLinks ${shacl.propertyPrefixed} ?propertyShape . - - VALUES ?propertyP { - ${shacl.targetClassPrefixed} - ${shacl.pathPrefixed} - ${shacl.classPrefixed} - ${shacl.namePrefixed} - } - ?propertyShape ?propertyP ?propertyO . - OPTIONAL { - ?propertyShape ${shacl.pathPrefixed} ?path . - ?path ${shacl.inversePathPrefixed} ?inversePath . - } - } UNION { - # incoming links - { - SELECT ?incomingLinks ?inAggregate ?inShape ?type WHERE { - BIND (<${type}> AS ?type) - ?inShape ${shacl.targetClassPrefixed} ?type . - ?inShape ${shacl.groupPrefixed} ?inAggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?incomingLinks ${blueprint.targetPrefixed} ?inAggregate . - ?incomingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . - } - } - VALUES ?linkP { - ${shacl.targetClassPrefixed} - ${shacl.propertyPrefixed} - ${blueprint.targetPrefixed} - ${rdf.typePrefixed} - } - ?incomingLinks ${blueprint.inverseLabelPrefixed} ?inverseLabel . - ?incomingLinks ?linkP ?linkO . - } UNION { - # incoming links sh:property - { - SELECT ?incomingLinks WHERE { - BIND (<${type}> AS ?type) - ?shape ${shacl.targetClassPrefixed} ?type . - ?shape ${shacl.groupPrefixed} ?aggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?incomingLinks ${blueprint.targetPrefixed} ?aggregate . - ?incomingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . - } - } - ?incomingLinks ${shacl.propertyPrefixed} ?propertyShape . - VALUES ?propertyP { - ${shacl.targetClassPrefixed} - ${shacl.pathPrefixed} - ${shacl.classPrefixed} - ${shacl.namePrefixed} - } - ?propertyShape ?propertyP ?propertyO . - OPTIONAL { - ?propertyShape ${shacl.pathPrefixed} ?path . - ?path ${shacl.inversePathPrefixed} ?inversePath . - } - } - } - `; - return query; -} - -function compositionToNodeLinksForClassQuery(type: string): string { - const query = ` - ${shacl.sparqlPrefix()} - ${blueprint.sparqlPrefix()} - ${rdfs.sparqlPrefix()} - ${rdf.sparqlPrefix()} - - CONSTRUCT { - - ?outgoingLinks ?linkP ?linkO . - ?propertyShape ?propertyP ?propertyO . - ?path ${shacl.inversePathPrefixed} ?inversePath . - - ?inShape ${shacl.groupPrefixed} ?inAggregate . - ?inShape ${shacl.targetClassPrefixed} ?type. - - ?incomingLinks ?linkP ?linkO . - ?incomingLinks ${rdfs.labelPrefixed} ?inverseLabel . - - } - WHERE { - { - # outgoing links - if this side is a A - { - SELECT ?outgoingLinks ?aggregate ?shape ?type WHERE { - BIND (<${type}> AS ?type) - ?shape ${shacl.targetClassPrefixed} ?type . - ?shape ${shacl.groupPrefixed} ?aggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . - ?outgoingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . - } - } - VALUES ?linkP { - ${shacl.targetClassPrefixed} - ${shacl.propertyPrefixed} - ${blueprint.targetPrefixed} - ${rdfs.labelPrefixed} - ${rdf.typePrefixed} - } - ?outgoingLinks ?linkP ?linkO . - } UNION { - # outgoing links sh:property - { - SELECT ?outgoingLinks WHERE { - BIND (<${type}> AS ?type) - ?shape ${shacl.targetClassPrefixed} ?type . - ?shape ${shacl.groupPrefixed} ?aggregate . - ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. - ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . - ?outgoingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . - } - } - - ?outgoingLinks ${shacl.propertyPrefixed} ?propertyShape . - - VALUES ?propertyP { - ${shacl.targetClassPrefixed} - ${shacl.pathPrefixed} - ${shacl.classPrefixed} - ${shacl.namePrefixed} - } - ?propertyShape ?propertyP ?propertyO . - OPTIONAL { - ?propertyShape ${shacl.pathPrefixed} ?path . - ?path ${shacl.inversePathPrefixed} ?inversePath . - } - } UNION { - # incoming links - { - SELECT ?incomingLinks ?type WHERE { - BIND (<${type}> AS ?type) - ?incomingLinks ${blueprint.targetPrefixed} ?type . - ?incomingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . - } - } - VALUES ?linkP { - ${shacl.targetClassPrefixed} - ${shacl.propertyPrefixed} - ${blueprint.targetPrefixed} - ${rdf.typePrefixed} - } - ?incomingLinks ${blueprint.inverseLabelPrefixed} ?inverseLabel . - ?incomingLinks ?linkP ?linkO . - } UNION { - # incoming links sh:property - { - SELECT ?incomingLinks WHERE { - BIND (<${type}> AS ?type) - ?incomingLinks ${blueprint.targetPrefixed} ?type . - ?incomingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . - } - } - ?incomingLinks ${shacl.propertyPrefixed} ?propertyShape . - VALUES ?propertyP { - ${shacl.targetClassPrefixed} - ${shacl.pathPrefixed} - ${shacl.classPrefixed} - ${shacl.namePrefixed} - } - ?propertyShape ?propertyP ?propertyO . - OPTIONAL { - ?propertyShape ${shacl.pathPrefixed} ?path . - ?path ${shacl.inversePathPrefixed} ?inversePath . - } - } - } - `; - return query; -} diff --git a/projects/blueprint/src/app/core/service/graph/aggregate/model/composition/composition-to-node-link.ts b/projects/blueprint/src/app/core/service/graph/aggregate/model/composition/composition-to-node-link.ts index fcc7cfb..407a508 100644 --- a/projects/blueprint/src/app/core/service/graph/aggregate/model/composition/composition-to-node-link.ts +++ b/projects/blueprint/src/app/core/service/graph/aggregate/model/composition/composition-to-node-link.ts @@ -109,7 +109,6 @@ export class CompositionToNodeLink extends ClownfaceObject implements ICompositi const shClass = p.out(shacl.classNamedNode).values[0]; const cfPath = p.out(shacl.pathNamedNode).toArray()[0]; const pathFactory = new OutgoingPathFactory(); - debugger; const path = pathFactory.createPath(cfPath); return [new PathDefinition(targetClass, shClass, path.toPathFragments())]; diff --git a/projects/blueprint/src/app/core/service/graph/aggregate/model/path-definition.ts b/projects/blueprint/src/app/core/service/graph/aggregate/model/path-definition.ts index c7a1a5d..42d12c0 100644 --- a/projects/blueprint/src/app/core/service/graph/aggregate/model/path-definition.ts +++ b/projects/blueprint/src/app/core/service/graph/aggregate/model/path-definition.ts @@ -19,7 +19,7 @@ export class PathDefinition { } get path(): string { - return this.#pathFragments.join(' '); + return this.#pathFragments.join('/'); } /** diff --git a/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-composition-links-for-class.query.ts b/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-composition-links-for-class.query.ts new file mode 100644 index 0000000..22d50c8 --- /dev/null +++ b/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-composition-links-for-class.query.ts @@ -0,0 +1,141 @@ +import { shacl, blueprint, rdfs, rdf } from "@blueprint/ontology"; + +export function compositionToCompositionLinksForClassQuery(type: string): string { + const query = ` + ${shacl.sparqlPrefix()} + ${blueprint.sparqlPrefix()} + ${rdfs.sparqlPrefix()} + ${rdf.sparqlPrefix()} + + CONSTRUCT { + ?shape ${shacl.groupPrefixed} ?aggregate . + ?shape ${shacl.targetClassPrefixed} ?type . + + ?outgoingLinks ?linkP ?linkO . + ?propertyShape ?propertyP ?propertyO . + ?path ${shacl.inversePathPrefixed} ?inversePath . + + ?inShape ${shacl.groupPrefixed} ?inAggregate . + ?inShape ${shacl.targetClassPrefixed} ?type. + + ?incomingLinks ?linkP ?linkO . + ?incomingLinks ${rdfs.labelPrefixed} ?inverseLabel . + + ?listRest rdf:first ?head . + ?head ?pHead ?oHead . + ?listRest rdf:rest ?tail . + } + WHERE { + { + # outgoing links + { + SELECT ?outgoingLinks ?aggregate ?shape ?type WHERE { + BIND (<${type}> AS ?type) + ?shape ${shacl.targetClassPrefixed} ?type . + ?shape ${shacl.groupPrefixed} ?aggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . + ?outgoingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . + } + } + VALUES ?linkP { + ${shacl.targetClassPrefixed} + ${shacl.propertyPrefixed} + ${blueprint.targetPrefixed} + ${rdfs.labelPrefixed} + ${rdf.typePrefixed} + } + ?outgoingLinks ?linkP ?linkO . + } UNION { + # outgoing links sh:property + { + SELECT ?outgoingLinks WHERE { + BIND (<${type}> AS ?type) + ?shape ${shacl.targetClassPrefixed} ?type . + ?shape ${shacl.groupPrefixed} ?aggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . + ?outgoingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . + } + } + + ?outgoingLinks ${shacl.propertyPrefixed} ?propertyShape . + + VALUES ?propertyP { + ${shacl.targetClassPrefixed} + ${shacl.pathPrefixed} + ${shacl.classPrefixed} + ${shacl.namePrefixed} + } + ?propertyShape ?propertyP ?propertyO . + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path ${shacl.inversePathPrefixed} ?inversePath . + } + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path rdf:rest* ?listRest . + ?listRest rdf:first ?head . + OPTIONAL { + ?head ?pHead ?oHead . + } + ?listRest rdf:rest ?tail . + } + } UNION { + # incoming links + { + SELECT ?incomingLinks ?inAggregate ?inShape ?type WHERE { + BIND (<${type}> AS ?type) + ?inShape ${shacl.targetClassPrefixed} ?type . + ?inShape ${shacl.groupPrefixed} ?inAggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?incomingLinks ${blueprint.targetPrefixed} ?inAggregate . + ?incomingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . + } + } + VALUES ?linkP { + ${shacl.targetClassPrefixed} + ${shacl.propertyPrefixed} + ${blueprint.targetPrefixed} + ${rdf.typePrefixed} + } + ?incomingLinks ${blueprint.inverseLabelPrefixed} ?inverseLabel . + ?incomingLinks ?linkP ?linkO . + } UNION { + # incoming links sh:property + { + SELECT ?incomingLinks WHERE { + BIND (<${type}> AS ?type) + ?shape ${shacl.targetClassPrefixed} ?type . + ?shape ${shacl.groupPrefixed} ?aggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?incomingLinks ${blueprint.targetPrefixed} ?aggregate . + ?incomingLinks a ${blueprint.CompositionToCompositionLinkPrefixed} . + } + } + ?incomingLinks ${shacl.propertyPrefixed} ?propertyShape . + VALUES ?propertyP { + ${shacl.targetClassPrefixed} + ${shacl.pathPrefixed} + ${shacl.classPrefixed} + ${shacl.namePrefixed} + } + ?propertyShape ?propertyP ?propertyO . + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path ${shacl.inversePathPrefixed} ?inversePath . + } + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path rdf:rest* ?listRest . + ?listRest rdf:first ?head . + OPTIONAL { + ?head ?pHead ?oHead . + } + ?listRest rdf:rest ?tail . + } + } + } + `; + return query; +} diff --git a/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-node-links-for-class.query.ts b/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-node-links-for-class.query.ts new file mode 100644 index 0000000..8d14bda --- /dev/null +++ b/projects/blueprint/src/app/core/service/graph/aggregate/query/composition-to-node-links-for-class.query.ts @@ -0,0 +1,134 @@ +import { shacl, blueprint, rdfs, rdf } from "@blueprint/ontology"; + +export function compositionToNodeLinksForClassQuery(type: string): string { + const query = ` + ${shacl.sparqlPrefix()} + ${blueprint.sparqlPrefix()} + ${rdfs.sparqlPrefix()} + ${rdf.sparqlPrefix()} + + CONSTRUCT { + + ?outgoingLinks ?linkP ?linkO . + ?propertyShape ?propertyP ?propertyO . + ?path ${shacl.inversePathPrefixed} ?inversePath . + + ?inShape ${shacl.groupPrefixed} ?inAggregate . + ?inShape ${shacl.targetClassPrefixed} ?type. + + ?incomingLinks ?linkP ?linkO . + ?incomingLinks ${rdfs.labelPrefixed} ?inverseLabel . + + ?listRest rdf:first ?head . + ?head ?pHead ?oHead . + ?listRest rdf:rest ?tail . + } + WHERE { + { + # outgoing links - if this side is a A + { + SELECT ?outgoingLinks ?aggregate ?shape ?type WHERE { + BIND (<${type}> AS ?type) + ?shape ${shacl.targetClassPrefixed} ?type . + ?shape ${shacl.groupPrefixed} ?aggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . + ?outgoingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . + } + } + VALUES ?linkP { + ${shacl.targetClassPrefixed} + ${shacl.propertyPrefixed} + ${blueprint.targetPrefixed} + ${rdfs.labelPrefixed} + ${rdf.typePrefixed} + } + ?outgoingLinks ?linkP ?linkO . + } UNION { + # outgoing links sh:property + { + SELECT ?outgoingLinks WHERE { + BIND (<${type}> AS ?type) + ?shape ${shacl.targetClassPrefixed} ?type . + ?shape ${shacl.groupPrefixed} ?aggregate . + ?aggregate ${rdf.typePrefixed} ${blueprint.CompositionPrefixed}. + ?outgoingLinks ${shacl.targetClassPrefixed} ?aggregate . + ?outgoingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . + } + } + + ?outgoingLinks ${shacl.propertyPrefixed} ?propertyShape . + + VALUES ?propertyP { + ${shacl.targetClassPrefixed} + ${shacl.pathPrefixed} + ${shacl.classPrefixed} + ${shacl.namePrefixed} + } + ?propertyShape ?propertyP ?propertyO . + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path ${shacl.inversePathPrefixed} ?inversePath . + } + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path rdf:rest* ?listRest . + ?listRest rdf:first ?head . + OPTIONAL { + ?head ?pHead ?oHead . + } + ?listRest rdf:rest ?tail . + } + + } UNION { + # incoming links + { + SELECT ?incomingLinks ?type WHERE { + BIND (<${type}> AS ?type) + ?incomingLinks ${blueprint.targetPrefixed} ?type . + ?incomingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . + } + } + VALUES ?linkP { + ${shacl.targetClassPrefixed} + ${shacl.propertyPrefixed} + ${blueprint.targetPrefixed} + ${rdf.typePrefixed} + } + ?incomingLinks ${blueprint.inverseLabelPrefixed} ?inverseLabel . + ?incomingLinks ?linkP ?linkO . + } UNION { + # incoming links sh:property + { + SELECT ?incomingLinks WHERE { + BIND (<${type}> AS ?type) + ?incomingLinks ${blueprint.targetPrefixed} ?type . + ?incomingLinks a ${blueprint.CompositionToNodeLinkPrefixed} . + } + } + ?incomingLinks ${shacl.propertyPrefixed} ?propertyShape . + VALUES ?propertyP { + ${shacl.targetClassPrefixed} + ${shacl.pathPrefixed} + ${shacl.classPrefixed} + ${shacl.namePrefixed} + } + ?propertyShape ?propertyP ?propertyO . + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path ${shacl.inversePathPrefixed} ?inversePath . + } + OPTIONAL { + ?propertyShape ${shacl.pathPrefixed} ?path . + ?path rdf:rest* ?listRest . + ?listRest rdf:first ?head . + OPTIONAL { + ?head ?pHead ?oHead . + } + ?listRest rdf:rest ?tail . + } + } + } + `; + return query; +} diff --git a/projects/blueprint/src/app/features/search/services/search/full-text-search/neptune-full-text-search/neptune-full-text-search.class.ts b/projects/blueprint/src/app/features/search/services/search/full-text-search/neptune-full-text-search/neptune-full-text-search.class.ts index 81d9f80..022efc4 100644 --- a/projects/blueprint/src/app/features/search/services/search/full-text-search/neptune-full-text-search/neptune-full-text-search.class.ts +++ b/projects/blueprint/src/app/features/search/services/search/full-text-search/neptune-full-text-search/neptune-full-text-search.class.ts @@ -20,11 +20,6 @@ export class NeptuneFullTextSearch extends FullTextSearch { } ).join(' || ')})` : ''; - console.log('sparqlFilterClause', sparqlFilterTerm); - /* const fluxClassQueries = metadata - .map(metaShape => fluxClassSubQuery(metaShape)) - .join(' UNION'); - */ const query = searchQueryWithSearchTerm( this._searchContext.searchTerm.toString(), sparqlFilterTerm, @@ -129,7 +124,6 @@ function searchQueryWithSearchTerm(searchTerm: string, filterTerm: string, pageN } `; - console.log('searchQueryWithSearchTerm', query); return query; } diff --git a/projects/blueprint/src/config.json b/projects/blueprint/src/config.json index 41babc3..be93f89 100644 --- a/projects/blueprint/src/config.json +++ b/projects/blueprint/src/config.json @@ -3,7 +3,7 @@ "endpointUrl": "https://ld.flux.zazuko.com/query", "sparqlConsoleUrl": "https://ld.flux.zazuko.com/sparql/#query", "graphExplorerUrl": "https://ld.flux.zazuko.com/graph-explorer/?resource", - "fullTextSearchDialect": "fuseki", + "fullTextSearchDialect": "stardog", "neptune": { "ftsEndpoint": " https://vpc-opensearch-zazuko-blueprint-glbaecqrcqwr5om3z5jj2duuiq.eu-central-1.es.amazonaws.com" }