Free text search in sparql when you have multiword and scaping character - sparql

I am wondering how I can use in sparql query when I have a word like :
Robert J. O'Neill
I am looking for the resource that have the multiword unit with quota or unicode character in the Label property.
SELECT DISTINCT ?resource ?abstract
WHERE {?resource rdfs:label ?s.
?s <bif:contains> "'Robert J. O'Neill'"
?resource dbo:abstract ?abstract
}
'''

Here is the query that will return all the elements that have "Robert J. O'Neill" as label.
SELECT DISTINCT ?s WHERE
{
?s rdfs:label ?label .
FILTER(regex(?label, "Robert J. O'Neill", "i"))
}
If you are sure that you need a specific string matching. This is faster :
SELECT DISTINCT ?s WHERE
{
?s rdfs:label ?label .
?label bif:contains "Robert J. O'Neill"
}
But be aware that, Virtuoso for example doesnt support such a query because of the spaces in the string. So an alternative is to avoid it as :
SELECT DISTINCT * WHERE
{
?s rdfs:label ?label .
?label bif:contains "Robert" .
FILTER (CONTAINS(?label, " J. O'Neill"))
}

I found following code faster that the regex:
SELECT ?s WHERE { ?s rdfs:label ?o FILTER ( bif:contains ( ?o, '"Robert" AND "J." AND "Neill"' ) ) }

Related

Concatenate one column over a resultset like kind of group_concat

I am currently writing on a SPARQL query (GraphDB) and try to concatenate the results of one column to avoid the kind of "duplicates".
My current query looks like this
SELECT ?label ?otaupdater
WHERE {
?charger rdf:type mymodel:SoftwarePackage.
?charger mymodel:isCompatibleWith ?target.
?target car:CarId <93718293>.
?charger rdfs:label ?label.
?otaupdater rdf:type mymodel:OTAUpdater.
?charger mymodel:isCompatibleWith ?otaupdater.
}
which gives me a resultset like
label
otaupdater
Chargie_One
123
Chargie_One
456
Chargie_Two
123
I tried to work in the command group_concat but only got so far that I ended up with
SELECT (group_concat(?otaupdater; separator=", ") AS ?otaupdaters) where { ... }
but this only returns all otaupdaters in one builded list.
What I am trying to achieve is something like this:
label
otaupdaters
Chargie_One
123, 456
Chargie_Two
123
The comment of #UninformedUser
lead to the answer:
SELECT ?charger ?label ?target (group_concat(?otaupdater; separator=", ") AS ?otaupdaters)
WHERE {
?charger rdf:type mymodel:SoftwarePackage.
?charger mymodel:isCompatibleWith ?target.
?target car:CarId <93718293>.
?charger rdfs:label ?label.
?otaupdater rdf:type mymodel:OTAUpdater.
?charger mymodel:isCompatibleWith ?otaupdater.
}
GROUP BY ?charger ?label ?target

Query in Sparql to get data of a person

I would like to have a list of all mountains names of the "dbo:firstAscentPerson" property of Lionel Terray (dbpedia: http://dbpedia.org/page/Lionel_Terray).
This below is what I have so far
select ?person ?firstAscentPerson where {
?person foaf:name "Lionel Terray"#en.
dbo:firstAscentPerson rdfs:label ?firstAscentPerson.
} LIMIT 100
The following query does what you need:
SELECT ?mountain ?mountainName ?person2 ?person2Name {
VALUES ?person1Name {"Lionel Terray"#en}
?mountain dbo:firstAscentPerson ?person1, ?person2 .
?mountain rdfs:label ?mountainName .
?person1 foaf:name ?person1Name .
FILTER (lang(?mountainName) = "en")
OPTIONAL {?person2 foaf:name ?person2Name . FILTER (lang(?person2Name) = 'en')}
}

How to add conditions to a query

I would like to add a condition to a query, so that, if a result is empty, it fills it with a result of another query.
For example : If a owl:Class has no "skos:definition", I would like to replace it by a "rdfs:comment"
Is this possible ?
Thank you !
COALESCE is can help, especially as you get more choices from skos:prefLabel, skos:altLabel and more.
OPTIONAL { ?property rdfs:label ?label }
OPTIONAL { ?property skos:definition ?definition .}
# ... other ways to choose ?comment ...
BIND ( COALESCE(?definition, ?label, "Unknown") AS ?comment )
COALESCE allows expressions (unlike BOUND)
https://www.w3.org/TR/sparql11-query/#func-coalesce
I found something with BIND (IF(BOUND(...) ..., ...) AS ...) statement.
SELECT DISTINCT ?type ?property ?comment ?propertyType ?domain
WHERE {
?property rens:hasAttributeType ?propertyType .
?property rens:hasForDomain ?domain .
?property rdf:type ?type .
?property rdfs:label ?label .
OPTIONAL {?property skos:definition ?definition .}
BIND(IF(BOUND(?definition), ?definition, ?label) AS ?comment) .
}
Is this the better way ?

Aggregate properties

I'm developing my own Fuseki endpoint from some DBpedia data.
I'm in doubt on how to aggregate properties related to a single resource.
SELECT ?name ?website ?abstract ?genre ?image
WHERE{
VALUES ?s {<http://dbpedia.org/resource/Attack_Attack!>}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image } .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}
SPARQL endpoint: http://dbpedia.org/sparql/
This query returns 2 matching results. They are different just for the dbo:genre value. There is a way I can query the knowledge base and retrieving a single result with a list of genres?
#chrisis's query works well on the DBpedia SPARQL Endpoint, which is based on Virtuoso.
However, if you are using Jena Fuseki, you should use more conformant syntax:
PREFIX dbo: <http://dbpedia.org/ontology/>
PREFIX dbp: <http://dbpedia.org/property/>
SELECT
?name
(SAMPLE(?website) AS ?sample_website)
(SAMPLE(?abstract) AS ?sample_abstract)
(SAMPLE(?image) AS ?sample_image)
(GROUP_CONCAT(?genre; separator=', ') AS ?genres)
WHERE {
VALUES (?s) {(<http://dbpedia.org/resource/Attack_Attack!>)}
?s foaf:name ?name ;
dbo:abstract ?abstract .
OPTIONAL { ?s dbo:genre ?genre } .
OPTIONAL { ?s dbp:website ?website } .
OPTIONAL { ?s dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
} GROUP BY ?name
The differences from the #chrisis's query are:
Since GROUP_CONCAT is an aggregation function, it might be used with GROUP BY only;
Since GROUP BY is used, all non-grouping variables should be aggregated (e.g. via SAMPLE);
GROUP_CONCAT syntax is slightly different.
In Fuseki, these AS in the projection are in fact superfluous: see this question and comments.
Yes, the GROUP_CONCAT() function is what you want.
SELECT ?name ?website ?abstract (GROUP_CONCAT(?genre,',') AS ?genres) ?image
WHERE{
<http://dbpedia.org/resource/Attack_Attack!> a dbo:Band ;
foaf:name ?name;
dbo:abstract ?abstract .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:genre ?genre } .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbp:website ?website} .
OPTIONAL{ <http://dbpedia.org/resource/Attack_Attack!> dbo:image ?image} .
FILTER LANGMATCHES(LANG(?abstract ), "en")
}

How the pass the output of one sparql query as a input to another sparql query

I am trying get the dbpedia movie link using the movie name in the first query and pass that link in the second query to get the movies similar to this movie.For e.g Lagaan.Now instead of passing the link manually in the second query is there a way to combine the two queries and pass the output of first query as an input to the second query.i.e:the link of the movie lagaan.Also,if the first query gives multiple links eg:if i am searching for Harry potter it will return multiple harry potter series links so,it should handle that case as well.
Query1
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix dbpedia-owl: <http://dbpedia.org/ontology/>
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
limit 10
Query 2
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/>
select ?similar (count(?p) as ?similarity) where {
values ?movie { <http://dbpedia.org/resource/Lagaan> }
?similar ?p ?o ; a dbpedia-owl:Film .
?movie ?p ?o .
}
group by ?similar ?movie
having count(?p) > 35
order by desc(?similarity)
Edited query:
select ?film ?similar (count(?p) as ?similarity) where {
{
select distinct ?film where {
?film a dbpedia-owl:Film .
?film rdfs:label ?label .
filter regex( str(?label), "Lagaan", "i")
}
}
?similar ?p ?o ; a dbpedia-owl:Film .
?film ?p ?o .
}
group by ?similar ?film
having count(?p) > 35
order by desc(?similarity)
corrected query as told by Joshua Taylor
select ?film ?other (count(*) as ?similarity) {
{
select ?film where {
?film a dbpedia-owl:Film ; rdfs:label ?label .
filter contains(lcase(?label),"lagaan")
}
limit 1
}
?film ?p ?o .
?other a dbpedia-owl:Film ; ?p ?o .
}
group by ?film ?other
having count(?p) > 25
order by desc(?similarity)
is there a way to combine the two queries and pass the output of first
query as an input to the second query.
SPARQL 1.1 defines subqueries. The results of inner queries are available to outer queries, so they are "passed" to them. In your case, you would have something along the lines of:
select ?similarMovie (... as ?similarity) where {
{ #-- QUERY 1, find one or more films
select distinct ?film where {
#-- ...
}
}
#-- QUERY 2, find films similar to ?film
#-- ...
}