박광하
박광하

Reputation: 29

Why does my sparql query get no result?

I made sparql query for grouping result and executed the query through the SPARQL endpoint http://glam.iptime.org/sparql.

But, I got no results and no error messages.

Query is like below.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX cfo: <http://lod.culture.go.kr/ontology/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?age ?typeName (count(?s) as ?cnt)
WHERE {
{
select * where {  
?s rdf:type cfo:CulturalObject.
?s rdfs:label ?label.
?s cfo:temporal ?time.
?time cfo:begin ?begin.    

BIND (STRDT(replace(?begin, 'BC', '-'), xsd:float) as ?year).
BIND(IF(?year > 1897, "modern", IF(?year > 1392, "chosun", IF(?year > 918, "goryeo", IF(?year > 700, "north_south", IF(?year > -58, "three_states", "ancient"))))) as ?age).

?s dc:type ?type.
?type  rdfs:label  ?typeName.
 } 
} 
 FILTER(BOUND(?age)).
}
GROUP BY ?age ?typeName
LIMIT 100

Does My sparql query have a problem? What problem does it have?

I think that sparql query declaration order is false. Any other opinion?

Upvotes: 2

Views: 1082

Answers (2)

evsheino
evsheino

Reputation: 2277

Some of the years in the data include some characters which seem to break things. One solution to this, if you want to exclude rows that have an empty ?age, is to filter out values containing such the chars with a regex, like so: FILTER(REGEX(?begin, "^(BC )?[0-9]+$"))

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX cfo: <http://lod.culture.go.kr/ontology/>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

SELECT ?age ?typeName (count(?s) as ?cnt) WHERE {
  ?s rdf:type cfo:CulturalObject.
  ?s rdfs:label ?label.
  ?s cfo:temporal ?time.
  ?time cfo:begin ?begin.
  # Filter the dates
  FILTER(REGEX(?begin, "^(BC )?[0-9]+$"))
  ?s dc:type ?type.
  ?type  rdfs:label  ?typeName. 
  BIND (STRDT(replace(?begin, 'BC ', '-'), xsd:integer) as ?year).
  BIND(IF(?year > 1897,"modern", 
            IF(?year > 1392, "chosun",
              IF(?year > 918, "goryeo",
                IF(?year > 700, "north_south",
                  IF(?year > -58, "three_states",
                      "ancient"))))) as ?age)
}
GROUP BY ?age ?typeName
LIMIT 100

You don't need the sub-query you have in your query.

The following query gets all the cfo:begin values that contain non-word characters (including the problematic characters).

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX cfo: <http://lod.culture.go.kr/ontology/>

SELECT ?begin (count(?s) as ?cnt) WHERE 
{
  ?s cfo:temporal ?time.
  ?time cfo:begin ?begin.  
  FILTER(REGEX(?begin, "\\W"))
}
GROUP BY ?begin
LIMIT 100

By the way, I recommend YASGUI for trying out queries, if you're not already familiar with it.

Upvotes: 2

scotthenninger
scotthenninger

Reputation: 4001

Instead of doing the work for you and hitting the endpoint with your query, I'd like to tell you how to approach the problem. Basically build the query pedantically. Start with a single triple pattern. Execute the query - LIMIT is your friend here. Then add the next triple pattern. Experiment with the results as you go.

So the first query would simply be:

SELECT *
WHERE {
   ?s a cfo:CulturalObject.
} LIMIT 100

Execute that, check that it gets the results. Next query is:

SELECT *
WHERE {
   ?s a cfo:CulturalObject.
   ?s rdfs:label ?label.
} LIMIT 100

Let's say this fails - you get no results. So maybe they used skos:prefLabel instead. SPARQL is a very exploratory language, so you could try the following:

SELECT *
WHERE {
   ?s a cfo:CulturalObject.
   ?s ?p ?o
} LIMIT 100

Check the values of ?p and ?o to see how the data is actually structured. Increase the LIMIT to see a bit more. Use the results to build the next triple pattern.

In the end, it's all about exploring the data, and unlike OWL or similar query languages, you need almost no knowledge of the data to execute a successful query. In fact, just so you know, the following query will ALWAYS yield results, unless the data store is empty:

SELECT ?s ?p ?o
WHERE {
   ?s ?p ?o .
} LIMIT 1000

As stated in the comment, sub-select is almost always a mistake unless the sub-select is computing aggregates. It's a SPARQL anti-pattern I see a lot, and I can only assume there are some examples out there that use sub-selects improperly. Just something to be aware of.

Upvotes: 7

Related Questions