sparql query to get all objects

371 views
Skip to first unread message

Kasia Kryczka

unread,
Jan 4, 2024, 9:52:03 AMJan 4
to TopBraid Suite Users
Hi,

This might be a simple question but I got stuck. 

I want to get all object from an ontology which are of a owl:Class but which are also defined in all the includes of that particular ontology. 

Any help would be great.

Thanks,

Kasia


Holger Knublauch

unread,
Jan 4, 2024, 10:02:09 AMJan 4
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
Are you using the SPARQL endpoint? Then activate the Include Imports checkbox.

From the SPARQL query panel, it would be something like

SELECT ?instance
WHERE {
    ?instance rdf:type/rdfs:subClassOf* ex:SomeClass .
}

which would also get the instances of the subclasses of the given class.

Holger



--
The topics of this mailing list include TopBraid EDG and related technologies such as SHACL.
To post to this group, send email to topbrai...@googlegroups.com
---
You received this message because you are subscribed to the Google Groups "TopBraid Suite Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to topbraid-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/topbraid-users/9315cc2f-a166-47b0-ab9d-7b320f2f527dn%40googlegroups.com.

Kasia Kryczka

unread,
Jan 5, 2024, 2:46:26 AMJan 5
to TopBraid Suite Users
Hi Holger, 

thank you for quick reply. 
The thing is I don't want to use the include imports checkbox. I want to have a query which I can later use in ADS.
Br,

Kasia

Holger Knublauch

unread,
Jan 5, 2024, 3:05:47 AMJan 5
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
In ADS you can write

let instances = graph.withDataGraph(dataset.withImports('urn:x-evn-master:geo'), () =>
graph.select(`
SELECT ?instance
WHERE {
?instance a skos:Concept .
}
`))
instances.bindings

Holger

Kasia Kryczka

unread,
Jan 5, 2024, 3:32:59 AMJan 5
to TopBraid Suite Users
Hi Holger, 

ok, but this still doesn't give me everything I need. I get like a part of all the results from imports.  Unfortynately I cannot post pictures. 
My ontology has   owl:imports <http://datashapes.org/graphql> ;
  owl:imports <http://topbraid.org/teamworkconstraints> ;
  owl:imports <urn:x-evn-master:ontology_1> ;
  owl:imports <urn:x-evn-master:ontology_2> ;
  owl:imports <urn:x-evn-master: ontology_3  > ;
  owl:imports <urn:x-evn-master: taxonomy_1> ;
  owl:imports <urn:x-evn-master: ontology_4  > ;
 
in the class hierarchy I can see more objects sth like that :

Data Object 
 - Abstract Object 
      - Level 2 Object 
          -Level 3 Object 
      -Level 2 Object 
- Conceptual Object 
   - Level 2 Object 
          -Level 3 Object 
      -Level 2 Object etc.
   

and all of them are from imports there are only 3 which are locally defined.
I would like to get all with a sparql query if that's possible. 
Hope this clarifies a bit. 

Br,

Kasia

Holger Knublauch

unread,
Jan 5, 2024, 4:53:11 AMJan 5
to topbrai...@googlegroups.com
To get instances of a class and its subclasses, use this trick from further below,

SELECT ?instance
WHERE {
    ?instance rdf:type/rdfs:subClassOf* ex:SomeClass .
}

This can also be rewritten as

SELECT ?instance
WHERE {
?type rdfs:subClassOf* ex:SomeClass .
?instance a ?type .
}

Holger


Kasia Kryczka

unread,
Jan 5, 2024, 9:51:50 AMJan 5
to TopBraid Suite Users
Hi Holger, 


I used a different thing  as I need to add a change history to all these objects: I used the following :


let graphURI = 'urn:x-evn-master:test';
graph.withDataGraph(graphURI, () => {
    let usedURIs = graph.withDataGraph(graphURI + '.tch', () => {
        return graph.select(`
            SELECT DISTINCT ?uri
            WHERE {
                ?t teamwork:subject|teamwork:predicate|teamwork:object ?uri .
                FILTER isIRI(?uri) .
            }`).bindings.map(b => b.uri.uri);
    });

    console.log('Found ' + usedURIs.length);
    let orphans = graph.withDataGraph(dataset.withImports(graphURI), () =>
        graph.select(`SELECT ?subject  WHERE { ?subject a owl:Class.  FILTER isIRI(?subject) }`))
        .bindings
        .map(b => b.subject)
          .filter(subject => !usedURIs.includes(subject.uri));
   
    orphans.forEach((orphan) => {
        console.log('Orphan is ' + orphan.uri);
        let triples = graph.triples(orphan, null, null);
        graph.transaction(graphURI + '.tch', 'Create dummy change for ' + orphan.uri, () => {
            let uuid = graph.eval('STRUUID()');
            let change = graph.namedNode('urn:x-change:' + uuid);
            console.log('Change: ' + change.uri);
            graph.update(`
                PREFIX dcterms: <http://purl.org/dc/terms/>
                PREFIX sioc: <http://rdfs.org/sioc/ns#>
                INSERT {
                    $change rdf:type teamwork:Change ;
                        rdfs:comment "Dummy change entry for ${orphan.uri}";
                        dcterms:created ?now ;
                        sioc:has_creator  <urn:x-tb-users:Anonymous4>;
                        teamwork:status   teamwork:Committed .
                }
                WHERE {
                    BIND (NOW() AS ?now) .
                }`, {
                    change: change
                });
            triples.forEach(triple => {
                triple.change = change;
                graph.update(`
                    INSERT {
                        $change teamwork:added [
                            teamwork:object     $object ;
                            teamwork:predicate  $predicate ;
                            teamwork:subject    $subject ;
                        ]
                    } WHERE {}`, triple);
            });
        });
    });
   
   return orphans; // Return the list of orphans after processing
});



it shows result in the change history but nothing gets added, the change is empty. 

Could you have a look and let me know what should be changed ?


Thank you, 

Kasia

Holger Knublauch

unread,
Jan 5, 2024, 9:56:26 AMJan 5
to topbrai...@googlegroups.com
Here, $change would be unbound. So you either need to insert that into the query string or pre-bind it:

                graph.update(`
                    INSERT {
                        <${change.uri}> teamwork:added [
                            teamwork:object     $object ;
                            teamwork:predicate  $predicate ;
                            teamwork:subject    $subject ;
                        ]
                    } WHERE {}`, triple);

HTH
Holger


Kasia Kryczka

unread,
Jan 8, 2024, 7:23:48 AMJan 8
to TopBraid Suite Users
Hi Holger, 

Unfortunately, it doesn't work. 
I get the comment but nothing gets added. The record is empty.  
When i look at the console I see correct "orphans" and I changed so the  usedURIs  should be a match when filtering but the result is the same. 

let graphURI = 'urn:x-evn-master:test';
graph.withDataGraph(graphURI, () => {
    let usedURIs = graph.withDataGraph(graphURI + '.tch', () => {
        return graph.select(`
            SELECT DISTINCT ?uri
            WHERE {
                ?t ?o ?uri .
                FILTER isIRI(?uri) .
            }`).bindings.map(b => b.uri.uri);
    });
    console.log('Found ' + usedURIs.length);
    // console.log(usedURIs);

Am I missing sth ?

Br,

Kasia

Holger Knublauch

unread,
Jan 8, 2024, 7:45:49 AMJan 8
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
Ok thanks, I better see what you're trying to do now. My previous "hint" was not helpful.

I ran the script in my test setup and think there is a mismatch between the use of imported graphs:

When you collect the orphans it will walk into the subgraphs, which in my case found imported classes including owl:Thing and owl:Nothing. I don't think you really want to have change history entries for those.

let orphans = graph.withDataGraph(dataset.withImports(graphURI)

But then when you ask for triples, you're only getting the locally defined triples:

  let triples = graph.triples(orphan, null, null);

Shouldn't both do the same thing and use imported graphs consistently?

Why did you want to use dataset.withImports in the first case?

In my local tests I can see a dummy change history entry created just fine, assuming the owl:Class is defined locally.

Also, to double-check, you really want to only find newly defined owl:Classes and not their instances?

Holger


Kasia Kryczka

unread,
Jan 8, 2024, 8:03:46 AMJan 8
to TopBraid Suite Users
Hi Holger,

I got a request to create a dummy change history comment for all owl:Class both defined locally and those which are included from all imports. 
These   owl:Thing and owl:Nothing do not need to have a dummy comment but I have much more included classes from imports.

Br,

Kasia

Holger Knublauch

unread,
Jan 8, 2024, 8:08:02 AMJan 8
to topbrai...@googlegroups.com
Ok in that case, use something like

let triples = graph.withDataGraph(dataset.withImports(graphURI), () => graph.triples(orphan));

(You will likely want to filter out owl:Thing and all kinds of other classes that will be listed.)

Holger


Kasia Kryczka

unread,
Jan 10, 2024, 6:59:52 AMJan 10
to TopBraid Suite Users
Hi Holger,

This is great :)

Thank you,

Br,

Kasia

Kasia Kryczka

unread,
Jan 30, 2024, 5:58:54 AMJan 30
to TopBraid Suite Users
Hi Holger,


Unfortunately, the solution does not give the expected results. 

It appears that when we add the history of changes to all the includes, the history is saved in the included ontology and not in the collection we are in.
 
Could you please advise whether this script can be adapted so that the history of includes is saved in the collection we are in, or whether this is not possible?

Br,

Kasia

Holger Knublauch

unread,
Jan 30, 2024, 6:02:17 AMJan 30
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
Could you paste the code that you have right now so that I can see the full context?

Thanks
Holger


Kasia Kryczka

unread,
Jan 30, 2024, 7:04:26 AMJan 30
to TopBraid Suite Users
Sure,

let graphURI = 'urn:x-evn-master:test';
graph.withDataGraph(graphURI, () => {
    let usedURIs = graph.withDataGraph(graphURI + '.tch', () => {
        return graph.select(`
            SELECT DISTINCT ?uri
            WHERE {
                ?t ?o ?uri .
                FILTER isIRI(?uri) .
            }`).bindings.map(b => b.uri.uri);
    });
    console.log('Found ' + usedURIs.length);
    // console.log(usedURIs);

 let orphans = graph.withDataGraph(dataset.withImports(graphURI), () =>
        graph.select(`SELECT ?subject
  WHERE {{?class a owl:Class.  
    BIND(?class as ?subject)
      }
UNION
{SELECT ?class2
   WHERE {{?instances a ?class.
    BIND(?instances as ?subject)
        }}}
  FILTER (?subject != "")
  FILTER isIRI(?subject).
  FILTER((?subject != owl:Thing) &&(?subject != owl:Nothing ))

}`))
        .bindings
        .map(b => b.subject)
          .filter(subject => !usedURIs.includes(subject.uri));
    orphans.forEach((orphan) => {
        console.log('Orphan is ' + orphan.uri);
         let triples = graph.withDataGraph(dataset.withImports(graphURI), () => graph.triples(orphan));

                graph.transaction(graphURI + '.tch', 'Create dummy change for ' + orphan.uri, () => {
            let uuid = graph.eval('STRUUID()');
            let change = graph.namedNode('urn:x-change:' + uuid);
            console.log('Change: ' + change.uri);
             console.log(change.uri);
             console.log(orphans)

              graph.update(`
                PREFIX dcterms: <http://purl.org/dc/terms/>
                PREFIX sioc: <http://rdfs.org/sioc/ns#>
                prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
                prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
                INSERT {
                    <${change.uri}> rdf:type teamwork:Change ;

                        rdfs:comment "Dummy change entry for ${orphan.uri}";
                        dcterms:created ?now ;
                        sioc:has_creator  <urn:x-tb-users:test>;

                        teamwork:status   teamwork:Committed .
                }
                WHERE {
                    BIND (NOW() AS ?now) .
                }`, {
                    $change : change

                });
            triples.forEach(triple => {
                triple.change = change;
                graph.update(`
                    INSERT {
                        <${change.uri}> teamwork:added [
                            teamwork:object     $object ;
                            teamwork:predicate  $predicate ;
                            teamwork:subject    $subject ;
                        ]
                    } WHERE {}`, triple);

    });
     })
})
 return orphans;
});


Br,

Kasia

Holger Knublauch

unread,
Jan 30, 2024, 8:18:11 AMJan 30
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
I don't see why it would ever write to some imported graph - the graph.transaction clearly targets just the given graphURI.
It does however also collect unused classes from imported graphs, because the select query walks across those.

BTW note that with

SELECT ?subject
WHERE {
{
?class a owl:Class.
BIND (?class as ?subject)
}
UNION
{
SELECT ?class2
WHERE {
{
?instances a ?class.
BIND(?instances as ?subject)
}
}
}
FILTER (?subject != "")
FILTER isIRI(?subject).
FILTER((?subject != owl:Thing) && (?subject != owl:Nothing ))
}

the second branch of the UNION never returns any bindings for ?subject, as the SELECT only returns ?class2.
Also the FILTER (?subject != "") is unnecessary.

Overall I don't think that continuing such complex topics via email works well. I think you should check if professional services
hours can be used for this.

Regards,
Holger


Kasia Kryczka

unread,
Jan 30, 2024, 8:41:46 AMJan 30
to TopBraid Suite Users
Hi Holger,

as for this ?subject and ?class 2 it was my mistake. The query is correct with ?subject.
I'll check the hours and create a ticket :)

I have one more question. How to add  teamwork: editor and viewer. 

let id = tbs.createAssetCollection({
 typeLabel: "Glossary",
    name: "Test Glossary v4",
    description: "this is a test glossary"
});
let uri = graph.namedNode(tbs.assetCollectionURI(id));
graph.transaction(uri, 'Initializing asset collection ' + id, () => {
    uri.add(edg + 'subjectArea', graph.namedNode('urn:x-tb-governance:Test'));
    uri.add(teamwork + 'editor', tbs.userURI('test'));
    uri.add(teamwork + 'viewer', tbs.userURI('test'));
});
 




Br,

Kasia

Holger Knublauch

unread,
Jan 30, 2024, 8:44:29 AMJan 30
to 'Bohms, H.M. (Michel)' via TopBraid Suite Users
On 30 Jan 2024, at 2:41 pm, Kasia Kryczka <sparql...@gmail.com> wrote:

Hi Holger,

as for this ?subject and ?class 2 it was my mistake. The query is correct with ?subject.
I'll check the hours and create a ticket :)

I have one more question. How to add  teamwork: editor and viewer. 

let id = tbs.createAssetCollection({
 typeLabel: "Glossary",
    name: "Test Glossary v4",
    description: "this is a test glossary"
});
let uri = graph.namedNode(tbs.assetCollectionURI(id));
graph.transaction(uri, 'Initializing asset collection ' + id, () => {
    uri.add(edg + 'subjectArea', graph.namedNode('urn:x-tb-governance:Test'));
    uri.add(teamwork + 'editor', tbs.userURI('test'));
    uri.add(teamwork + 'viewer', tbs.userURI('test'));
});

Safest to use the full URI of that property, e.g. 'http://topbraid.org/teamwork#editor'

HTH
Holger


Kasia Kryczka

unread,
Jan 30, 2024, 8:55:58 AMJan 30
to TopBraid Suite Users
It worked, but I can see it in the source code :
  j.2:editor <urn:x-tb-users:test> ;
  j.2:viewer <urn:x-tb-users:test> ;

but not in the Users Panel but when I add uri.add(edg + 'dataSteward', tbs.userURI('Test User')); this one I can see in the users Panel.
Why is that ?

Br,

Kasia

Reply all
Reply to author
Forward
0 new messages