-
Notifications
You must be signed in to change notification settings - Fork 95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Combine default graph and optional graphs via UNION to return all the types available in the dataset #1327
base: skosmos-2
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1327 +/- ##
=========================================
Coverage 70.68% 70.68%
- Complexity 1646 1647 +1
=========================================
Files 32 32
Lines 3786 3787 +1
=========================================
+ Hits 2676 2677 +1
Misses 1110 1110
Continue to review full report at Codecov.
|
Thanks for giving this a shot @kinow , this has been a longstanding issue that has bitten many users (including yourself)! However, I'm not sure this is the right approach, adding lots of UNION clauses to the query which seems overcomplicated to me. The intent of the There are at least a few ways of doing that that I can think of:
Would you like to try some of the approaches 2-4? I think any of them would be an improvement over the current situation, as long as the query still performs well. |
Sounds like fun! I will give it a try later after or in between the other JQuery/Bootstrap work. Will be a good way to brush up SPARQL and Jena Fuseki :) Do you have any suggestion on which item to try first (or to start thinking about), between options 2, 3, and 4? Thanks! |
I think 3 or 4 would be most preferable as they don't suffer from the problem of irrelevant data being picked up from other possible named graphs in the dataset. |
model/sparql/GenericSparql.php
Outdated
private function generateQueryTypesQuery($lang) { | ||
$fcl = $this->generateFromClause(); | ||
private function generateQueryTypesQuery(string $lang): string { | ||
$vocabs = $this->model->getVocabularies(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there are no vocabs, then the query will return all the types from all the graphs. Would it be better to return an empty result int that case?
I decided to try Here's an example of what the query may look like. It is from my development environment with a few vocabularies configured. PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX isothes: <http://purl.org/iso25964/skos-thes#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX finaf: <http://urn.fi/URN:NBN:fi:au:finaf:>
SELECT DISTINCT ?type ?label ?superclass
FROM NAMED <http://skos.um.es/unescothes/>
FROM NAMED <http://zbw.eu/stw/>
FROM NAMED <http://vocabs.rossio.fcsh.unl.pt/tesauro/>
FROM NAMED <http://www.yso.fi/onto/yso/>
FROM NAMED finaf:
WHERE
{ GRAPH ?g
{ { { BIND(skos:Concept AS ?type) }
UNION
{ BIND(skos:Collection AS ?type) }
UNION
{ BIND(isothes:ConceptGroup AS ?type) }
UNION
{ BIND(isothes:ThesaurusArray AS ?type) }
UNION
{ ?type rdfs:subClassOf/(rdfs:subClassOf)* skos:Concept }
UNION
{ ?type rdfs:subClassOf/(rdfs:subClassOf)* skos:Collection }
}
OPTIONAL
{ ?type rdfs:label ?label
FILTER langMatches(lang(?label), "en")
}
OPTIONAL
{ ?type rdfs:subClassOf ?superclass }
FILTER EXISTS { ?s a ?type ;
skos:prefLabel ?prefLabel
}
}
} And the REST API response: {
"@context": {
"skos": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#",
"uri": "@id",
"type": "@type",
"rdfs": "http:\\/\\/www.w3.org\\/2000\\/01\\/rdf-schema#",
"onki": "http:\\/\\/schema.onki.fi\\/onki#",
"label": "rdfs:label",
"superclass": {
"@id": "rdfs:subClassOf",
"@type": "@id"
},
"types": "onki:hasType",
"@language": "en",
"@base": "http:\\/\\/localhost:9090\\/rest\\/v1\\/"
},
"uri": "",
"types": [
{
"uri": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept",
"label": "Concept"
},
{
"uri": "http:\\/\\/zbw.eu\\/namespaces\\/zbw-extensions\\/Descriptor",
"label": "Descriptor",
"superclass": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept"
},
{
"uri": "http:\\/\\/zbw.eu\\/namespaces\\/zbw-extensions\\/Thsys",
"label": "Thsys",
"superclass": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept"
},
{
"uri": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Collection",
"label": "Collection"
},
{
"uri": "http:\\/\\/purl.org\\/iso25964\\/skos-thes#ConceptGroup",
"label": "Concept group"
},
{
"uri": "http:\\/\\/purl.org\\/iso25964\\/skos-thes#ThesaurusArray",
"label": "Array of sibling concepts"
},
{
"uri": "http:\\/\\/www.yso.fi\\/onto\\/yso-meta\\/Concept",
"label": "General concept",
"superclass": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept"
},
{
"uri": "http:\\/\\/www.yso.fi\\/onto\\/yso-meta\\/Individual",
"label": "Individual concept",
"superclass": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept"
},
{
"uri": "http:\\/\\/www.yso.fi\\/onto\\/yso-meta\\/Hierarchy",
"label": "Hierarchical concept",
"superclass": "http:\\/\\/www.w3.org\\/2004\\/02\\/skos\\/core#Concept"
}
]
} |
), | ||
'http://www.w3.org/2004/02/skos/core#Collection' => array(), | ||
'http://purl.org/iso25964/skos-thes#ThesaurusArray' => array(), | ||
'http://purl.org/iso25964/skos-thes#ConceptGroup' => array() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had a look at testconfig.ttl
, and I think the function shuold return these new types now as they are types used in vocabularies there. These extra values are added now since the query is searching types in all graphs for all configured vocabs.
SonarCloud Quality Gate failed. 0 Bugs No Coverage information |
'http://www.w3.org/2004/02/skos/core#Concept', | ||
'http://www.w3.org/2004/02/skos/core#Collection', | ||
'http://purl.org/iso25964/skos-thes#ThesaurusArray', | ||
'http://purl.org/iso25964/skos-thes#ConceptGroup', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only change in this array is the order of ThesaurusArray
and ConceptGroup
. Not sure why these two swapped places in this array.
The SonarCloud security issue reported is for a prefix URL, so that shouldn't be a blocker, I think. Ready for review again 👍 |
FILTER EXISTS { | ||
?s a ?type . | ||
?s skos:prefLabel ?prefLabel . | ||
GRAPH ?g { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks wrong to me. You are already using $fcl
i.e. a generated block of FROM clauses. There is no need for the GRAPH ?g {
block.
Reasons for creating this PR
Only the types of the default graph are returned in the REST API, unless the user enables the option in Jena that includes all graphs.
Link to relevant issue(s), if any
Description of the changes in this PR
In the parts of the query where it references types (like rdfs label, or a subclass, etc) I have added a sibling
UNION
that includes theGRAPH ?g { same_statement }
, to simulate what Jena does with that setting.With the changes in this branch, after clearing the Local Storage in my browser, I can see all the types in both the REST response, and also in the UI (e.g. search auto-complete, see #1323 ), without needing to enable that option to merge the default graph in Jena Fuseki.
Known problems or uncertainties in this PR
Does it need a test? Does it sound like a valid solution? I thought about doing a simpler
{ { query_as_is } UNION { GRAPH ?g { query _as is } } }
but since the query wasn't very long I opted for this current approach.Checklist