UNION.A sample scenario demonstrating the usage of the core feature of SPARQL logic of pattern matching:
SPARQL PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX dgtwc: <http://data-gov.tw.rpi.edu/2009/data-gov-twc.rdf#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dbpedia: <http://dbpedia.org/resource/> PREFIX conversion: <http://purl.org/twc/vocab/conversion/> PREFIX upstream: <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/vocab/enhancement/1/> SELECT ( count(DISTINCT ?dataset) as ?numresult ) WHERE { GRAPH <http://purl.org/twc/vocab/conversion/MetaDataset> { ?dataset a conversion:CatalogedDataset . ?dataset dcterms:title ?title . ?abstract void:inDataset <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/version/2012-Apr-14> . ?abstract upstream:most_recent_scrape ?versioned . ?dataset void:inDataset ?versioned . { { ?dataset dcterms:title ?title . ?title bif:contains '"healthcare"' . } UNION { ?dataset dcterms:description ?description . ?description bif:contains '"healthcare"' . } UNION { ?dataset dgtwc:keywords ?keywords . ?keywords bif:contains '"healthcare"' . } } } } ;
SPARQL PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX dgtwc: <http://data-gov.tw.rpi.edu/2009/data-gov-twc.rdf#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dbpedia: <http://dbpedia.org/resource/> PREFIX conversion: <http://purl.org/twc/vocab/conversion/> PREFIX upstream: <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/vocab/enhancement/1/> SELECT * WHERE { GRAPH <http://purl.org/twc/vocab/conversion/MetaDataset> { { { ?dataset dcterms:title ?t . ?t bif:contains '"healthcare"' . } UNION { ?dataset dcterms:description ?description . ?description bif:contains '"healthcare"' . } UNION { ?dataset dgtwc:keywords ?keywords . ?keywords bif:contains '"healthcare"' . } } ?dataset a conversion:CatalogedDataset . ?dataset dcterms:title ?title . ?dataset void:inDataset ?versioned . ?abstract void:inDataset <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/version/2012-Apr-14> . ?abstract upstream:most_recent_scrape ?versioned . } }
?dataset had multiple titles, the bif:contains in the second query may match a ?t value that contains "healthcare" while ?title is bound to other values (potentially not containing "healthcare").
However, consider two cases: ?dataset has some dcterms:title for which ?t bif:contains '"healthcare"'.
In this case two other branches of UNION are not needed, ?dataset is found anyway, and additional ?dataset dcterms:title ?title is needed only if you want to enumerate all titles of the ?dataset, otherwise ?t is the most adequate because ?t bif:contains '"healthcare"' already.
?dataset does not have any dcterms:title with the '"healthcare"' word, but it contains some appropriate description or comment.
In this case the original query gets ?title not bound and thus the whole match for ?dataset fails.
SELECT ( COALESCE (?good_title, ?some_title)) ... WHERE { { ?dataset dcterms:title ?good_title . ?good_title bif:contains '"healthcare"' . } UNION { ?dataset dcterms:description ?description . ?description bif:contains '"healthcare"' . } UNION { ?dataset dgtwc:keywords ?keywords . ?keywords bif:contains '"healthcare"' . } } ... ?dataset dcterms:title ?some_title ... 1 Another variant is also: <verbatim> SELECT (COALESCE (?good_title, ( SELECT ?some_title ... WHERE { ?dataset dcterms:title ?some_title } ) ) ) ... WHERE { { ?dataset dcterms:title ?good_title . ?good_title bif:contains '"healthcare"' . } UNION { ?dataset dcterms:description ?description . ?description bif:contains '"healthcare"' . } UNION { ?dataset dgtwc:keywords ?keywords . ?keywords bif:contains '"healthcare"' . } } ...
COALESCE() or SPARQL-BI <bif:coalesce>() built-in function, depending on features supported by the server.
That's the simplest way to "prioritize" values.
?catalog_title and ?catalog_subtitle OPTIONAL and thus postponed to the end even if grouping is required for these two specific properties.
So the fixed query will look like:
SPARQL PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX dcterms: <http://purl.org/dc/terms/> PREFIX dgtwc: <http://data-gov.tw.rpi.edu/2009/data-gov-twc.rdf#> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX dbpedia: <http://dbpedia.org/resource/> PREFIX conversion: <http://purl.org/twc/vocab/conversion/> PREFIX upstream: <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/vocab/enhancement/1/> PREFIX void: <http://rdfs.org/ns/void#> PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> SELECT (?catalog_title AS ?id) (?catalog_subtitle AS ?label) (COUNT(DISTINCT ?dataset) AS ?count) WHERE { GRAPH <http://purl.org/twc/vocab/conversion/MetaDataset> { { { ?dataset dcterms:title ?title . ?title bif:contains '"health"' . } UNION { ?dataset dcterms:description ?description . ?description bif:contains '"health"' . } UNION { ?dataset dgtwc:keywords ?keywords . ?keywords bif:contains '"health"' . } } [ void:subset ?versioned ] void:inDataset <http://logd.tw.rpi.edu/source/twc-rpi-edu/dataset/iogds-upstream/version/2012-Apr-14> . ?dataset void:inDataset ?versioned . ?dataset a conversion:CatalogedDataset . OPTIONAL { ?dataset dgtwc:catalog_title ?catalog_title . ?dataset dgtwc:catalog_subtitle ?catalog_subtitle . } FILTER(bound (?catalog_title)) . FILTER(bound (?catalog_subtitle)) . } } GROUP BY ?catalog_title ?catalog_subtitle ;