sparql wikidata - how to only show statements without any references

86 views Asked by At

I am trying to gather all statements for a specific topic (let's say Václav Havel - Q36233) but I need to exclude all statements that include any reference.

SELECT ?subjectLabel ?property ?object ?objectLabel
    WHERE {
      ?subject ?property ?object.
      FILTER (?subject = wd:Q36233)
      FILTER(REGEX(STR(?property), "http://www.wikidata.org/prop/.*"))
      FILTER(REGEX(STR(?object), "http://www.wikidata.org/entity/Q.*"))
      SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

This query results in 194 statements but among those are statements that also include references.

I need the result list to include this: 0 references = show

But not include this: 1+ references = not show

I tried many ways of changing the query by adding MINUS operator and FILTER operator, but none of those worked and usually resulted in 0 results.

1

There are 1 answers

7
logi-kal On BEST ANSWER

You can use this query:

SELECT DISTINCT ?subjectLabel ?property ?object ?objectLabel
WHERE {
  ?subject ?property ?object .
  ?subject ?p ?stmt.
  ?stmt ?ps ?object .
  
  BIND (URI(REPLACE(STR(?p),STR(p:),STR(wdt:))) as ?property)
  BIND (URI(REPLACE(STR(?p),STR(p:),STR(ps:))) as ?ps)
  
  FILTER (?subject = wd:Q36233)
  FILTER (REGEX(STR(?p), STR(p:)))
  FILTER (REGEX(STR(?object), STR(wd:)))
  FILTER NOT EXISTS { ?stmt prov:wasDerivedFrom ?ref . }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}

where FILTER NOT EXISTS { ?stmt prov:wasDerivedFrom ?ref . } is checking that the statement ?stmt does not have a references.

Note that ?subject ?p ?stmt. ?stmt ?ps ?object . is almost equivalent to ?subject ?property ?object ., except that the wdt: prefix searches for best statement (for example excluding deprecated ones), while the p: prefix does not. Thus ?subject ?property ?object . is not redundant because in general you cannot safely remove it.

A more efficient version using Blazergraph's QueryHints:

SELECT DISTINCT ?subjectLabel ?property ?object ?objectLabel
WHERE {
  ?subject ?property ?object .
  {
    SELECT ?subject ?p ?stmt ?object (URI(REPLACE(STR(?p),STR(p:),STR(wdt:))) as ?property)
    WHERE {
      ?subject ?p ?stmt.
      ?stmt ?ps ?object .
      BIND (URI(REPLACE(STR(?p),STR(p:),STR(ps:))) as ?ps)
      FILTER (?subject = wd:Q36233)
      FILTER (REGEX(STR(?p), STR(p:)))
      FILTER (REGEX(STR(?object), STR(wd:)))
      hint:SubQuery hint:runOnce true .
    }
  }
  hint:Prior hint:runFirst true .
  FILTER NOT EXISTS { ?stmt prov:wasDerivedFrom ?ref . }
  SERVICE wikibase:label { bd:serviceParam wikibase:language "en". }
}