I need to search items in two graphs with the same string, but different language codes ("xx"#en and "xx"#eng - from wordnet). obviously
"xx"#en is not equal to "xx"#eng.
it can be done with (prefix nlp suitably defined):
select * where {
?a nlp:lemma ?as .
?b rdfs:label ?bs .
filter (str(?as)=str(?bs)) .
# more code using ?a and ?b
}
However, this query takes too long and is wasteful. It should be possible to do something like:
?a nlp:lemma ?s .
?b rdfs:label ?s .
but i cannot see how - short of manually change all #eng in the wordnet triples to #en - which i would rather not do.
any solution?
thank you!
You could cut you search space down by filtering only for en and eng, but the only way to compare the string portion of a language-labeled string is to convert them to a string.
I.e. the following could be more efficient if there are language-labeled strings other than en and eng:
select * where {
?a nlp:lemma ?as .
?b rdfs:label ?bs .
filter (lang(?as) = "en" || lang(?as) = "eng")
filter (str(?as)=str(?bs)) .
# more code using ?a and ?b
}
Related
I’m new to query languages and linked data so thanks a lot for the help. I also have a similar question about sparql on wikidata
Wikidata sparql query returns 0 result
I would like to look up all the art movements in dbpedia with the associated artists (associated with the movement -peopleNam, famous for the movement-famousName, influence the movement-influenceName) here is my query with lots of redundant prefix (that I could not enter because of the amount of links)
SELECT ?movementName ?famousName ?peopleName ?influenceName
WHERE {
?m dc:subject <http://dbpedia.org/resource/Category:Art_movements> .
?m rdfs:label ?movementName .
FILTER(LANG(?movementName) = "en")
?m dbp:knownFor ?a .
?a rdfs:label ?famousName .
FILTER(LANG(?famousName) = "en")
?m dbp:movement ?b .
?b rdfs:label ?peopleName .
FILTER(LANG(?peopleName) = "en")
?m dbp:influencedBy ?d .
?d rdfs:label ?influenceName .
FILTER(LANG(?influenceName) = "en")
}'
When I run the query with only the movement name I get 235 results but whenever I add any other artist name, I get 0 result. Could you show me what went wrong?
A similar query is done in wikidata with some encouraging results but I haven’t tried to match the two sources yet.
Thanks
How to list all literals of only selected OWL datatype (here :VisibilityKind) in SPARQL? The OWL datatype definition of VisibilityKind is:
DatatypeDefinition( :VisibilityKind
DataOneOf( "public"^^xsd:string "private"^^xsd:string "package"^^xsd:string )
)
With SPARQL, you can get all the literals that have a certain datatype IRI. For instance, assuming you have data with literals such as "public"^^:VisibilityKind, you can write:
SELECT ?literal WHERE {
?s ?p ?literal .
FILTER (datatype(?literal) = :VisibilityKind)
}
But this is certainly not what you want because you probably do not have literals with this datatype IRI. What you would probably like is something that could roughly be formulated as:
SELECT ?literal WHERE {
?s ?p ?literal .
FILTER (isInDatatype(?literal,:VisibilityKind))
}
where isInDatatype checks if the value associated with ?o belongs to the value space of :VisibilityKind. However, such function does not exist in standard SPARQL 1.1. Moreover, even if it existed, it would require the query engine to understand the semantics of OWL 2 and do reasoning. So you would need a SPARQL engine that implements the OWL 2 DL entailment regime and you'd have to hack a bit the query to get what you want:
SELECT ?literal WHERE {
?s ?p ?literal .
[] a :VisibilityKind;
:owl:sameAs ?literal;
FILTER (isLiteral(?literal))
}
If you want to find implementations of SPARQL 1.1 Entailment regimes, you could take a look at the implementation reports collected by the SPARQL working group.
To answer directly, you need to search for all values in the owl:oneOf list:
SELECT ?resource ?value
WHERE {
:VisibilityKind owl:equivalentClass / owl:oneOf / ( rdf:rest*/rdf:first ) ?value .
?resource ?prop ?value .
}
However, there is a caveat - other properties could have the value "public" "private" or "package". To ensure that you're getting only the values of :VisibilityKind, define that datatype as a range of properties that use the datatype:
{ :someProp rdfs:domain :VisibilityKind }
Then use the following query to get all properties that define :VisibilityKind in the range:
SELECT ?resource ?value
WHERE {
?prop rdfs:range :VisibilityKind .
?resource ?prop ?value
}
My goal is to graphically represent the S->P->O relations within a depth two edges from the specified resource, p:Person_1. I want all relations within that path length to be returned from my query as ?s, ?p, ?o for further processing in my graphical application.
I tried the first query below which gives me my first set of ?s ?p ?o with repeats, then ?p2, ?o2, ?p3, ?o3 as additional columns in the result. I want to bind ?p2 and ?p3 to ?p, ?o2 and ?o3 to ?o.
SELECT *
WHERE {
p:Person_1 ?p ?o .
BIND("p:Person_1" as ?s)
OPTIONAL{
?o ?p2 ?o2 .
}
OPTIONAL{
?o2 ?p3 ?o3 .
}
}
Then, based on How do I construct get the whole sub graph from a given resource in RDF Graph?, I tried using CONSTRUCT to return the graph.
PREFIX p: <http://www.example.org/person/>
PREFIX x: <example.org/foo/>
construct { ?s ?p ?o }
FROM <http://localhost:8890/MYGRAPH>
where { p:Person_1 (x:|!x:)* ?s .
?s ?p ?o .
}
I am using Virtuoso and I get the error:
Virtuoso 37000 Error SP031: SPARQL compiler: Variable ?_::trans_subj_9_3 in T_IN list is not a value from some triple
I could post-process the result from my first query but I want to learn how to do this correctly with SPARQL, preferably on Virtuoso.
Update after testing the advice from #AKSW :
Both CONSTRUCT and SELECT statements work with the pattern suggested.
CONSTRUCT { ?s ?p ?o }
FROM <http://localhost:8890/MYGRAPH>
where { p:Person_1 (x:foo|!x:bar)* ?s .
?s ?p ?o .
} LIMIT 100
and:
SELECT s ?p ?o
FROM <http://localhost:8890/MYGRAPH>
where { p:Person_1 (x:foo|!x:bar)* ?s .
?s ?p ?o .
} LIMIT 100
The SELECT results in several duplicates that cannot be removed using DISTINCT, which results in an error that I assume is due to the 'datatype' of some of the returned values.
Virtuoso 22023 Error SR066: Unsupported case in CONVERT (DATETIME -> IRI_ID)
It appears some post-SPARQL processing is in order.
This gets me most of the way there. Still hoping I can find a solution for SPARQL that is like Cypher's "number of hops away" :
OPTIONAL MATCH path=s-[*1..3]-(o)
Here is a SPARQL query that works in Virtuoso. Note the SPARQL W3C standard does not support this syntax and it will fail in other triplestores.
PREFIX p: <http://www.example.org/person/>
PREFIX x: <example.org/foo/>
# CONSTRUCT {?s ?p ?o} # If you wish to return the graph
SELECT ?s ?p ?o # To return the triples
FROM <http://localhost:8890/MYGRAPH>
where { p:Person_1 (x:foo|!x:bar){1,3} ?s .
?s ?p ?o .
}LIMIT 100
See also K. Idehen's wiki entry here: http://linkedwiki.com/exampleView.php?ex_id=141
And thanks to #Joshua Taylor for advice in the same area.
Working Drafts of SPARQL 1.1 Property Paths included the {n,m} operator for handling this issue, which was implemented (and will remain supported) in Virtuoso. Here's a tweak to #tim's response.
Live SPARQL Query Results Page using the DBpedia endpoint (which is a Virtuoso instance).
Live SPARQL Query Definition Page that opens up query source code in the default DBpedia query editor.
Actual Query Example:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?s AS ?Entity
?o AS ?Category
WHERE {
?s rdf:type <http://dbpedia.org/ontology/AcademicJournal> ;
rdf:type{1,3} ?o
}
LIMIT 100
Should you be looking for LinkedIn-like presentation of Contact Networks and Degrees of Separation between individuals, here is an example using Virtuoso-specific SPARQL Extensions that solve this particular issue:
SELECT ?o AS ?WebID
((SELECT COUNT (*) WHERE {?o foaf:knows ?xx})) AS ?contact_network_size
?dist AS ?DegreeOfSeparation
<http://www.w3.org/People/Berners-Lee/card#i> AS ?knowee
WHERE
{
{
SELECT ?s ?o
WHERE
{
?s foaf:knows ?o
}
} OPTION (TRANSITIVE, t_distinct, t_in(?s), t_out(?o), t_min (1), t_max (4), t_step ('step_no') AS ?dist) .
FILTER (?s= <http://www.w3.org/People/Berners-Lee/card#i>)
FILTER (isIRI(?s) and isIRI(?o))
}
ORDER BY ?dist DESC (?contact_network_size)
LIMIT 500
Note: this approach is the only way (at the current time) to expose actual relational hops between entities in an Entity Relationship Graph that includes Transitive relations.
Live Link to Query Results
Live Link to Query Source Code
Bearing in mind that the r{n,m} operator was deprecated in the final SPARQL 1.1 (but will remain supported in Virtuoso), you can use r/r?/r? instead of r{1,3}, if you want to work strictly off the current spec:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT DISTINCT ?s AS ?Entity
?o AS ?Category
WHERE {
?s rdf:type <http://dbpedia.org/ontology/AcademicJournal> ;
rdf:type / rdf:type? / rdf:type? ?o
}
LIMIT 100
Here's a live example, against the DBpedia instance hosted in Virtuoso.
I would like to get some places from DBPedia in certain area, and that would be easy if those points would had geometry property. However, all they have is georss:point. I have converted this to two doubles, but I cannot convert them to geo:geometry object that can be supplied to location filter.
The code I have thus far:
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
SELECT ?name
?abstract
?ns
?ew
WHERE
{ ?m foaf:name ?name
. ?m georss:point ?coord
. ?m <http://dbpedia.org/ontology/abstract> ?abstract
. BIND( xsd:double(strbefore( ?coord, " " )) AS ?ns )
BIND( xsd:double(strafter( ?coord, " " )) AS ?ew )
BIND( geo:Point(?ew, ?ns) AS ?geo ) # <-- I have problem with this
FILTER (bif:st_intersects (?geo, bif:st_point(?geo), 10))
FILTER (LANG(?abstract) = "en")
}
If you know any way to convert those or other filtering method, please enlighten me. :)
There is not enough information here to give you a simple and clear answer.
However, I think you may be able to figure it out from the examples in the GEOSPARQL documentation for Virtuoso, the DBMS engine which hosts DBpedia. There's more here.
I am trying to retrieve data from linkedgeodata.org/sparql
Prefix lgdo: <http://linkedgeodata.org/ontology/>
Select *
From <http://linkedgeodata.org>
{
?s a lgdo:Restaurant .
?s rdfs:label ?l .
?s geo:geometry ?g .
Filter(bif:st_intersects (?g, bif:st_point (48.143889, 17.109722), 5.1)) .
}
But response is empty. I want to retrieve restaurants in Bratislava....5km from coordinates.
I used similar sparql code like in the example, I changed only class to restaurant and coordinates of the city, so I dont know where I am doing mistake.(http://linkedgeodata.org/OnlineAccess/SparqlEndpoints?v=bpg)
Prefix lgdo: <http://linkedgeodata.org/ontology/>
Select *
From <http://linkedgeodata.org>
{
?s a lgdo:Amenity .
?s rdfs:label ?l .
?s geo:geometry ?g .
Filter(bif:st_intersects (?g, bif:st_point (12.372966, 51.310228), 0.1)) .
}
You can see all types of things that fall within those coordinates by running the following query:
Prefix lgdo: <http://linkedgeodata.org/ontology/>
Select ?type, count(?s)
From <http://linkedgeodata.org>
{
?s a ?type .
?s rdfs:label ?l .
?s geo:geometry ?g .
Filter(bif:st_intersects (?g, bif:st_point (48.143889, 17.109722), 5.1)) .
} GROUP BY ?type
This query, using GROUP BY and COUNT, gives you counts for all different types. As you can see there are no restaurants falling in geographical area. Your query is not wrong, the database does not contain any restaurants for the given coordinates.