def get_concept_hierarchy(self): # same as parent query, only: # running against rdflib in-memory graph, not SPARQL endpoint # a single graph, not a multi-graph (since it's an RDF/XML or Turtle file) """ Function to draw concept hierarchy for vocabulary """ def build_hierarchy(bindings_list, broader_concept=None, level=0): """ Recursive helper function to build hierarchy list from a bindings list Returns list of tuples: (<level>, <concept>, <concept_preflabel>, <broader_concept>) """ level += 1 # Start with level 1 for top concepts hierarchy = [] narrower_list = sorted( [ binding_dict for binding_dict in bindings_list if # Top concept ((broader_concept is None) and (binding_dict.get("broader_concept") is None)) or # Narrower concept ((binding_dict.get("broader_concept") is not None) and (binding_dict["broader_concept"] == broader_concept)) ], key=lambda binding_dict: binding_dict["concept_preflabel"], ) for binding_dict in narrower_list: concept = binding_dict["concept"] hierarchy += [( level, concept, binding_dict["concept_preflabel"], binding_dict["broader_concept"] if binding_dict.get("broader_concept") else None, )] + build_hierarchy(bindings_list, concept, level) return hierarchy vocab = g.VOCABS[self.vocab_id] q = """ PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> PREFIX skos: <http://www.w3.org/2004/02/skos/core#> PREFIX dct: <http://purl.org/dc/terms/> SELECT DISTINCT ?concept ?concept_preflabel ?broader_concept WHERE {{ {{ ?concept skos:inScheme <{vocab_uri}> . }} UNION {{ ?concept skos:topConceptOf <{vocab_uri}> . }} UNION {{ <{vocab_uri}> skos:hasTopConcept ?concept . }} ?concept skos:prefLabel ?concept_preflabel . OPTIONAL {{ ?concept skos:broader ?broader_concept . ?broader_concept skos:inScheme <{vocab_uri}> . }} FILTER(lang(?concept_preflabel) = "{language}" || lang(?concept_preflabel) = "") }} ORDER BY ?concept_preflabel""".format( vocab_uri=vocab.concept_scheme_uri, language=self.language) bindings_list = [] for r in self.gr.query(q): bindings_list.append({ # ?concept ?concept_preflabel ?broader_concept "concept": r[0], "concept_preflabel": r[1], "broader_concept": r[2], }) assert bindings_list is not None, "FILE concept hierarchy query failed" hierarchy = build_hierarchy(bindings_list) return Source.draw_concept_hierarchy(hierarchy, self.request, self.vocab_id)
def get_concept_hierarchy(self): # return FILE.hierarchy[self.vocab_id] pass g = FILE.load_pickle_graph(self.vocab_id) result = g.query( """ PREFIX skos: <http://www.w3.org/2004/02/skos/core#> SELECT (COUNT(?mid) AS ?length) ?c ?pl ?parent WHERE {{ ?c a skos:Concept . ?cs (skos:hasTopConcept | skos:narrower)* ?mid . ?mid (skos:hasTopConcept | skos:narrower)+ ?c . ?c skos:prefLabel ?pl . ?c (skos:topConceptOf | skos:broader) ?parent . FILTER (?cs = <{}>) }} GROUP BY ?c ?pl ?parent ORDER BY ?length ?parent ?pl """.format(self.uri) ) cs = [] for row in result: cs.append({ 'length': {'value': row['length']}, 'c': {'value': row['c']}, 'pl': {'value': row['pl']}, 'parent': {'value': row['parent']} }) hierarchy = [] previous_parent_uri = None last_index = 0 for c in cs: # insert all topConceptOf directly if str(c['parent']['value']) == self.uri: hierarchy.append(( int(c['length']['value']), c['c']['value'], c['pl']['value'], None )) else: # If this is not a topConcept, see if it has the same URI as the previous inserted Concept # If so, use that Concept's index + 1 this_parent = c['parent']['value'] if this_parent == previous_parent_uri: # use last inserted index hierarchy.insert(last_index + 1, ( int(c['length']['value']), c['c']['value'], c['pl']['value'], c['parent']['value'] )) last_index += 1 # This is not a TopConcept and it has a differnt parent from the previous insert # So insert it after it's parent else: i = 0 parent_index = 0 for t in hierarchy: if this_parent in t[1]: parent_index = i i += 1 hierarchy.insert(parent_index + 1, ( int(c['length']['value']), c['c']['value'], c['pl']['value'], c['parent']['value'] )) last_index = parent_index + 1 previous_parent_uri = this_parent return Source.draw_concept_hierarchy(hierarchy, self.request, self.vocab_id)
def get_concept_hierarchy(self, concept_scheme_uri): # returns an ordered list of tuples, (hierarchy level, Concept URI, Concept prefLabel) s = VOCBENCH('x', self.request)._authed_request_object() r = s.post(config.VB_ENDPOINT + '/SPARQL/evaluateQuery', data={ 'query': ''' PREFIX skos: <http://www.w3.org/2004/02/skos/core#> SELECT (COUNT(?mid) AS ?length) ?c ?pl ?parent WHERE {{ ?c a skos:Concept . ?cs (skos:hasTopConcept | skos:narrower)* ?mid . ?mid (skos:hasTopConcept | skos:narrower)+ ?c . ?c skos:prefLabel ?pl . ?c (skos:topConceptOf | skos:broader) ?parent . FILTER (?cs = <{}>) }} GROUP BY ?c ?pl ?parent ORDER BY ?length ?parent ?pl'''.format(concept_scheme_uri), 'ctx_project': self.vocab_id }) if r.status_code == 200: test = r.content.decode('utf-8') """<?xml version="1.0" encoding="UTF-8"?><stresponse request="evaluateQuery" type="error"> <msg>org.eclipse.rdf4j.repository.http.HTTPQueryEvaluationException: Query evaluation error: com.ontotext.trree.util.NotEnoughMemoryForDistinctGroupBy: Insufficient free Heap Memory 172Mb for group by and distinct, threshold:250Mb, reached 0Mb (HTTP status 500)</msg> </stresponse> """ cs = json.loads(r.content.decode( 'utf-8'))['result']['sparql']['results']['bindings'] hierarchy = [] previous_parent_uri = None last_index = 0 for c in cs: # insert all topConceptOf directly test = c if 'parent' not in c: continue if str(c['parent']['value']) == concept_scheme_uri: hierarchy.append((int(c['length']['value']), c['c']['value'], c['pl']['value'], None)) else: # If this is not a topConcept, see if it has the same URI as the previous inserted Concept # If so, use that Concept's index + 1 this_parent = c['parent']['value'] if this_parent == previous_parent_uri: # use last inserted index hierarchy.insert( last_index + 1, (int(c['length']['value']), c['c']['value'], c['pl']['value'], c['parent']['value'])) last_index += 1 # This is not a TopConcept and it has a differnt parent from the previous insert # So insert it after it's parent else: i = 0 parent_index = 0 for t in hierarchy: if this_parent in t[1]: parent_index = i i += 1 hierarchy.insert( parent_index + 1, (int(c['length']['value']), c['c']['value'], c['pl']['value'], c['parent']['value'])) last_index = parent_index + 1 previous_parent_uri = this_parent return Source.draw_concept_hierarchy(hierarchy, self.request, self.vocab_id) else: raise VbException('There was an error: ' + r.content.decode('utf-8'))