Search code examples
sparqldbpedia

Sparql find entities with dbo type and sort them by count


I have to do a sparql query to the dbpedia endpoint which needs to:

  1. Find all the entities containing "vienna" in the label and "city" in the abstract
  2. Filter them keeping only the ones that have at least one dbo rdf:type
  3. Sort the results by count of dbo types (e.g. if an entity has 5 dbo rdf:type it has to be shown before entities with 4 dbo rdf:type)

I did several attempts, the closest to the result is:

select distinct (str(?s) as ?s) count(?t) as ?total where {{ ?s rdfs:label "vienna"@en. ?s rdf:type ?t.} 
UNION { ?s rdfs:label ?l. ?s rdf:type ?t . ?l <bif:contains> '("vienna")'
. FILTER EXISTS { ?s dbo:abstract ?cc. ?cc <bif:contains> '("city")'. FILTER(lang(?cc) = "en").}} 
FILTER (!strstarts(str(?s), str("http://dbpedia.org/resource/Category:")))
. FILTER (!strstarts(str(?s), str("http://dbpedia.org/property/")))
. FILTER (!strstarts(str(?s), str("http://dbpedia.org/ontology/")))
. FILTER (strstarts(str(?t), str("http://dbpedia.org/ontology/"))).} 
LIMIT 50

Which will (wrongly) count the rdf:type before actually filtering it. I don't want to count rdf:type that are not dbo (ontology).


Solution

  • The idea is to use a subquery in which you search for the entities and to do the counting in the outer query:

    PREFIX  dbo:  <http://dbpedia.org/ontology/>
    PREFIX  rdf:  <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
    PREFIX  rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    
    SELECT  ?s (count(*) AS ?cnt)
    WHERE
      { { SELECT DISTINCT  ?s
          WHERE
            { ?s  rdfs:label      ?l .
              ?l  <bif:contains>  '"vienna"'
              FILTER langMatches(lang(?l), "en")
              FILTER EXISTS { ?s   dbo:abstract    ?cc .
                              ?cc  <bif:contains>  '"city"'
                              FILTER langMatches(lang(?cc), "en")
                            }
              ?s  rdf:type  ?t
              FILTER ( ! strstarts(str(?s), str("http://dbpedia.org/resource/Category:")) )
              FILTER ( ! strstarts(str(?s), str("http://dbpedia.org/property/")) )
              FILTER ( ! strstarts(str(?s), str(dbo:)) )
              FILTER strstarts(str(?t), str(dbo:))
            }
        }
        ?s  ?p  ?o
        FILTER strstarts(str(?p), str(dbo:))
      }
    GROUP BY ?s
    ORDER BY DESC(?cnt)