2

I am new to Semantic Web and SPARQL. I am making a RDFS of concert. It has songs entries like:

con:song04
    rdfs:Class con:Repertoire;
    rdfs:label "Deewani Mastani";
    con:performedBy con:artist02.
    con:performedBy con:artist05.

I am trying to get list of songs and their count, if they are performed by same artist. I have been trying some tutorials from stackoverflow but does not server my purpose.

The query I am using might be wrong completely, would be really helpful in learning, if someone could help me on this aspects. I am using Apache Jena Fuseki to query.

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX co: <http://rhizomik.net/ontologies/copyrightonto.owl#>
PREFIX dc: <http://purl.org/dc/elements/1.1/>
prefix con: <http://www.example.com/paras/concert#>

#Use SPARQL to count and list the songs that two artists share.
SELECT ?songs (COUNT(?artist) AS ?count)  
WHERE
{ 
  ?s rdfs:label ?songs .
  ?s rdf:type con:Repertoire.
  ?s con:performedBy ?artist.
  ?artist rdf:type con:Artist .
  filter( ?count > 1 )
}
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
  • 1
    This isn't an answer to your question, but important nonetheless: you are using the resource `rdfs:Class` wrong. It's a class name, not a property. The triple `con:song04 rdfs:Class con:Repertoire` does _not_ say that song 4 is in the class "Repertoire". If that is what you want to express, you should use `rdf:type` instead (which is the property that expresses instance-class relationships). – Jeen Broekstra Nov 23 '15 at 20:15
  • 1
    @JeenBroekstra: You mean to say, I should be saying `con:song04 ref:type con:Repertoire` instead? Please clarify, thanks – Parash Nath Mishra Nov 23 '15 at 21:55
  • 1
    Yes, minus the typo (it's `rdf`, not `ref`). – Jeen Broekstra Nov 23 '15 at 22:50
  • Thank you @JeenBroekstra – Parash Nath Mishra Nov 24 '15 at 10:17

2 Answers2

2
SELECT ?songs (COUNT(?artist) AS ?count)  
WHERE
{ 
  ?s rdfs:label ?songs .
  ?s rdfs:Class con:Repertoire.
  ?s con:performedBy ?artist.
  ?artist rdfs:Class con:Artist .
  filter( ?count > 1 )
}

If you paste that query into the validator at sparql.org, you see that it's an error to SELECT a variable that you haven't GROUPed BY when you're using aggregate functions like COUNT. Your query is almost correct though. You're trying to GROUP BY the song, and COUNT how many artists did that song. Then you want to take only the results HAVING a count greater than 1. You do that like this:

SELECT ?songs (COUNT(?artist) AS ?count)  
WHERE
{ 
  ?s rdfs:label ?songs .
  ?s rdfs:Class con:Repertoire.
  ?s con:performedBy ?artist.
  ?artist rdfs:Class con:Artist .
}
GROUP BY ?songs
HAVING (?count > 1 )
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • Hi @Joshua, Thanks, Your explanation helped me to understand better. You understood exactly what I was trying to do but I am not getting right answer. :( probably something I am missing, help would be appreciated. – Parash Nath Mishra Nov 23 '15 at 21:58
  • 2
    @ParashNathMishra WIthout knowing exactly what you're expecting as results, it will be difficult to help you fix the query. – Joshua Taylor Nov 23 '15 at 22:30
  • I am trying to list the songs that are performed by more than 2 artist. As mentioned in the question, I would want song04 listed as result as it is perfumed by 2 artists also, display the number of songs that satisfy the condition. – Parash Nath Mishra Nov 24 '15 at 10:19
  • @parash I don't have your data though. I don't know what my query returns on your data. Without access to your data, I can't debug a query on your data. – Joshua Taylor Nov 24 '15 at 12:44
1

According to description given, I totally agree with @Joshua Taylor and believe what you are trying to do can be achieved by the query. Please check if your RDFS is okay.

SELECT ?songs (COUNT(?artist) AS ?count)  
WHERE
{ 
  ?s rdfs:label ?songs .
  ?s rdfs:Class con:Repertoire.
  ?s con:performedBy ?artist.
  ?artist rdfs:Class con:Artist .
}
GROUP BY ?songs
HAVING (?count > 1 )