Query in Sparql, find first layer of transitive actual nodes - sparql

I'm trying to find all actual nodes 'directly'(ignore blank nodes) connect to target node.
eg.
Object1 <predicate1> ObjectX .
Object2 <predicate2> _:BlankNode1 .
_:BlankNode1 <predicate3> ObjectX .
Object3 <predicate4> _:BlankNode2 .
_:BlankNode2 <predicate5> _:BlankNode3 .
_:BlankNode3 <predicate6> ObjectX .
Object4 <predicate7> Object3 .
Is there a way I can find Object1, Object2 and Object3, but not Object4?
Thanks,
Shane.

You should try this:
SELECT ?object
WHERE {
?object (:p|!:p)+ :ObjectX . #The object is connected to the target via any property, with an arbitrary path length greater than 1.
FILTER NOT EXISTS {
?object (:p|!:p)+ ?notBlank . #But there is no path which involves a non-blank node.
?notBlank (:p|!:p)+ :ObjectX .
FILTER(!ISBLANK(?notBlank))
}
FILTER(!ISBLANK(?object)) #Finally, the object is not blank
}

Related

Access subclassOf/subclassOf level using ForwardChainingRDFSInferencer with SPARQL

I am running some SPARQL queries using the class ForwardChainingRDFSInferencer, which basic constructs an inferencer. For my examples I use the schema.org ontology.
My code looks like the following example
MemoryStore store = new MemoryStore();
ForwardChainingRDFSInferencer inferencer = new ForwardChainingRDFSInferencer(store); //the inference class
Repository repo = new SailRepository(inferencer);
repo.initialize();
URL data = new URL("file:/home/user/Documents/schemaorg-current-https.nt");
RDFFormat fileRDFFormat = RDFFormat.NTRIPLES;
RepositoryConnection con = repo.getConnection();
con.add(data, null, fileRDFFormat);
System.out.println("Repository loaded");
String queryString =
" PREFIX schema: <https://schema.org/>" +
" SELECT DISTINCT ?subclassName_one" +
" WHERE { " +
" ?type rdf:type rdfs:Class ." +
" ?type rdfs:subClassOf/rdfs:subClassOf? schema:Thing ." +
" ?type rdfs:label ?subclassName_one ." +
" }";
TupleQuery tupleQuery = con.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
TupleQueryResult result = tupleQuery.evaluate();
while (result.hasNext()) {
BindingSet bindingSet = result.next();
System.out.println(bindingSet.toString());
stdout.println(bindingSet.toString());
}
repo.close()
What I want is to print two subclass levels down the class Thing. So if for example we have,
Thing > Action (sub-class 1) > ConsumeAction (sub-class 2) > DrinkAction
What I want is to return the class CosumeAction which is two levels (subclasses) down from class Thing, while using the inference java class.
The current query, as given in the code sample above, returns all the classes and subclasses from every class of the schema.org ontology. Thus, there is something that I do wrong while using the inference class.
You could remove the classes you are not interested in with FILTER NOT EXISTS:
FILTER NOT EXISTS {
?type rdfs:subClassOf+/rdfs:subClassOf/rdfs:subClassOf schema:Thing .
}
Examples
For DrinkAction (level 3):
FILTER NOT EXISTS {
?type
rdfs:subClassOf+ / # schema:ConsumeAction
rdfs:subClassOf / # schema:Action
rdfs:subClassOf schema:Thing .
}
For WearAction (level 4):
FILTER NOT EXISTS {
?type
rdfs:subClassOf+ / # schema:UseAction / schema:ConsumeAction
rdfs:subClassOf / # schema:Action
rdfs:subClassOf schema:Thing .
}

SPARQL: get object only if predicate exists

I want to get the sources of a dbo:Cheese. Some dbo:Cheese have dbo:Animal as dbp:source. Some others have only text. I would like to get the source information in the ?sources variable regardless of that the source is dbo:Animal or text . How should I do it ?
SELECT ?cheese
CONCAT(GROUP_CONCAT(DISTINCT ?source; SEPARATOR=", "), ", ", GROUP_CONCAT(DISTINCT ?source_label; SEPARATOR=", ")) AS ?sources
WHERE {
?cheese a dbo:Cheese .
optional { # some cheeses don't have a source informed
?cheese dbp:source ?source .
}
optional { # some sources are dbo:Animal, some others are xsd:string
?source a dbo:Animal ;
rdfs:label ?source_label .
FILTER(langMatches(lang(?source_label), "EN"))
}
}
LIMIT 10
I tried this. Problem is that I have both http://dbpedia.org/resource/Sheep and Sheep in ?sources.

Why are some of the classes in my ontolgoy not being returned in my SPARQL query?

I'm rather confused about why I'm receiving too little results (256 expected, 224 returned). When I run the code below, everything returns exactly as I want it, except that I miss all the classes in my ontology which lie at the highest level, or one below the highest level. I don't understand where I'm being too "strict" in my query so that these classes are not being returned in the table. They also all have parent classes (whether that be the topmost class "top concept" of the ontology, or something like an enumeration type class, either way, the leaf should still be found. Would be thankful for tips or pointers where my code might be inadvertently filtering out those classes.
SELECT DISTINCT ?leaf ?parentclasses
WHERE {
GRAPH <>
#a leaf is the lowest level class: A class that does not have a subclass
{
{
{
#I want anything which is a class
{
?leaf rdf:type owl:Class.
}
#i also want the subclass of any superclass if that exists
{
?leaf rdfs:subClassOf ?superclass .
}
#squeezed to specific section of OTL.
filter strstarts(str(?leaf), "URIgoeshere")
#Only keep the results that do not have a preflabel
OPTIONAL {
?leaf skos:prefLabel ?subclasslabel.
}
#make sure the subclasslabel is in dutch
#filter( langMatches(lang(?subclasslabel),"nl") )
#give me the label of the superclass
OPTIONAL {
?superclass skos:prefLabel ?superclasslabel.
}
#make sure it's in dutch
FILTER (lang(?superclasslabel) = "nl")
#if it exists, give me also the superclass of the superclass creating a supersuperclass
{
?superclass rdfs:subClassOf ?supersuperclass.
#give me the label of the supersuperclass
OPTIONAL {
?supersuperclass skos:prefLabel ?supersuperclasslabel.
}
#make sure it's in dutch
FILTER (lang(?supersuperclasslabel) = "nl")
#keep the leafs that are NOT The values whereby the subclass is not empty. (double negative for removing leafs where the subclass has a subclass below it)
FILTER NOT EXISTS {
?subclass rdfs:subClassOf ?leaf
FILTER (?subclass != owl:Nothing )
}
#concatenate the two parentclass variables into one
BIND(concat(str(?superclasslabel), str("-"), str(?supersuperclasslabel) ) as ?parentclasses)
}
}
}
}
}
Here is a ttl file with the same structure as my database: https://file.io/jjwkAWbK4jrF
Below is my end solution to my problem. It was more complicated than I expected, but it works.
The problem was that these classes that didn't have a parent class were not being accepted by the query. With some union cases this could be covered for 0 parent classes, 1 parent class or 2 parent classes.
SELECT DISTINCT ?leaf ?parentclasses
WHERE {
GRAPH <>
#a leaf is the lowest level class: A class that does not have a subclass
{{{{{
#I want anything which is a class
{?leaf rdf:type owl:Class.}
#squeezed
filter strstarts(str(?leaf), "graph")
#keep the leafs that are NOT The values whereby the subclass is not empty.
(double negative for removing leafs where the subclass has a subclass below it)
FILTER NOT EXISTS {?subclass rdfs:subClassOf ?leaf
FILTER (?subclass != owl:Nothing ) }
}
{
{?leaf rdfs:subClassOf ?superclass .}
#grab dutch label if available
optional {
?superclass skos:prefLabel ?superclassnllabel .
filter( langMatches(lang(?superclassnllabel),"nl") )
}
# take either as the label, but dutch over empty
bind( coalesce( ?superclassnllabel, replace(str(?
superclass),"^[^#]*#", "" ) ) as ?superclasslabel )
{
{?superclass rdfs:subClassOf ?supersuperclass.}
#grab dutch label if available
?supersuperclass skos:prefLabel ?supersuperclassnllabel .
filter( langMatches(lang(?supersuperclassnllabel),"nl") )
# take either as the label, but dutch over empty
bind( coalesce( ?supersuperclassnllabel, replace(str(?
supersuperclass),"^[^#]*#", "" ) ) as ?supersuperclasslabel )
BIND(concat(str(?superclasslabel), str(" - "), str(?
supersuperclasslabel) ) as ?parentclasses)
}
union
{
{?superclass ?p ?o.filter(!isblank(?superclass))}
FILTER NOT EXISTS {?superclass rdfs:subClassOf ?supersuperclass}
BIND(concat(str(?superclasslabel), str(" - "), str("Top
Concept") ) as ?parentclasses)
#concatenate the two parentclass variables into one
}
}
}
union
{
#figure this out, WHY IS IT HERE?
{?leaf rdf:type owl:Class .filter(!isblank(?leaf))}
FILTER strstarts(str(?leaf), "graph")
FILTER NOT EXISTS {?leaf rdfs:subClassOf ?superclass}
FILTER NOT EXISTS {?subclass rdfs:subClassOf ?leaf
FILTER (?subclass != owl:Nothing ) }
BIND (str("Top Class") as ?parentclasses )
}
}}}}

Searching semantically tagged documents in MarkLogic

Can any one please point me to some simple examples of semantic tagging and querying semantically tagged documents in MarkLogic?
I am fairly new in this area,so some beginner level examples will do.
When you say "semantically tagged" do you mean regular XML documents that happen to have some triples in them? The discussion and examples at http://docs.marklogic.com/guide/semantics/embedded are pretty good for that.
Start by enabling the triple index in your database. Then insert a test doc. This is just XML, but the sem:triple element represents a semantic fact.
xdmp:document-insert(
'test.xml',
<test>
<source>AP Newswire</source>
<sem:triple date="1972-02-21" confidence="100">
<sem:subject>http://example.org/news/Nixon</sem:subject>
<sem:predicate>http://example.org/wentTo</sem:predicate>
<sem:object>China</sem:object>
</sem:triple>
</test>)
Then query it. The example query is pretty complicated. To understand what's going on I'd insert variations on that sample document, using different URIs instead of just test.xml, and see how the various query terms match up. Try using just the SPARQL component, without the extra cts query. Try cts:search with no SPARQL, just the cts:query.
xquery version "1.0-ml";
import module namespace sem = "http://marklogic.com/semantics"
at "/MarkLogic/semantics.xqy";
sem:sparql('
SELECT ?country
WHERE {
<http://example.org/news/Nixon> <http://example.org/wentTo> ?country
}
',
(),
(),
cts:and-query((
cts:path-range-query( "//sem:triple/#confidence", ">", 80) ,
cts:path-range-query( "//sem:triple/#date", "<", xs:date("1974-01-01")),
cts:or-query((
cts:element-value-query( xs:QName("source"), "AP Newswire"),
cts:element-value-query( xs:QName("source"), "BBC"))))))
In case you are talking about enriching your content using semantic technology, that is not directly provided by MarkLogic.
You can enrich your content externally, for instance by calling a public service like the one provided by OpenCalais, and then insert the enrichments to the content before insert.
You can also build lists of lookup values, and then using cts:highlight to mark such terms within your content. That could be as simple as:
let $labels := ("MarkLogic", "StackOverflow")
return
cts:highlight($doc, cts:word-query($labels), <b>{$cts:text}</b>)
Or with a more dynamic replacement using spraql:
let $labels := map:new()
let $_ :=
for $result in sem:sparql('
PREFIX demo: <http://www.marklogic.com/ontologies/demo#>
SELECT DISTINCT ?label
WHERE {
?s a demo:person.
{
?s demo:fullName ?label
} UNION {
?s demo:initialsName ?label
} UNION {
?s demo:email ?label
}
}
')
return
map:put($labels, map:get($result, 'label'), 'person')
return
cts:highlight($doc, cts:word-query(map:keys($labels)),
let $result := sem:sparql(concat('
PREFIX demo: <http://www.marklogic.com/ontologies/demo#>
SELECT DISTINCT ?s ?p
{
?s a demo:', map:get($labels, $cts:text), ' .
?s ?p "', $cts:text, '" .
}
'))
return
if (map:contains($labels, $cts:text))
then
element { xs:QName(fn:concat("demo:", map:get($labels, $cts:text))) } {
attribute subject { map:get($result, 's') },
attribute predicate { map:get($result, 'p') },
$cts:text
}
else ()
)
HTH!

How to solve SPARQL warning?

I am trying to retrieve the name of inkers of Comic books. I am trying to build an ontology. Inkers has dbpprop and I have imported rdlib and sparqlWrapper whilst I am having following error. Is there any one who understand this problem?
Abcde-MacBook-Pro:example Abcde$ python basicTest.py
WARNING:rdflib.term: does not look like a valid URI, trying to serialize this will break.
Abcde-MacBook-Pro:example Abcde$ python basicTest.py
Traceback (most recent call last):
File "basicTest.py", line 78, in <module>
g = sparql.query().convert()
File "build/bdist.macosx-10.10-intel/egg/SPARQLWrapper/Wrapper.py", line 535, in query
File "build/bdist.macosx-10.10-intel/egg/SPARQLWrapper/Wrapper.py", line 513, in _query
SPARQLWrapper.SPARQLExceptions.EndPointInternalError: EndPointInternalError: endpoint returned code 500 and response.
Response:
Virtuoso RDF01 Error Bad variable value in CONSTRUCT: "Malcolm Jones III" (tag 246 box flags 0) is not a valid subject, only object of a triple can be a literal
SPARQL query:
define sql:big-data-const 0
#output-format:application/rdf+xml
My code looks like
CONSTRUCT {
?comics ma:inked_by ?inker .
?inker rdf:type ma:Inker .
}
WHERE{
?comics rdf:type dbpedia-owl:Comics .
?comics foaf:name ?name .
OPTIONAL {?comics dbpprop:inkers ?inker}
FILTER regex(str(?name), "Batman")
}"""
I think the problem arises when you get the ?inker out. Sometime it is a URI and sometime it is a string. For example, the following are the top two outputs:
"Malcolm Jones III"
http://dbpedia.org/resource/Vince_Colletta
I think you need to change your code in a way that your inker is either a URI or a string. The following will save the URI in your ontology, if it exists. If you need a string use the ?inkername instead.
CONSTRUCT {
?comics ma:inked_by ?inker.
?inker a ma:Inker.
}
where {
?comics a dbpedia-owl:Comics.
?comics foaf:name ?name .
optional{
?comics dbpprop:inkers ?inker.
?inker foaf:name ?inkername.
}
FILTER regex(str(?name), "Batman")
}