2013-07-31 2 views
2

У меня есть таблицы в моей базе данных MySQL, как:SPARQL запрос, чтобы получить все родительский узел

+-------+------------+-------------+-----------+ 
| ID | subject | Predicate | object | 
+-------+------------+-------------+-----------+ 
| 1 | ATM  | subClassof | Network | 
+-------+------------+-------------+-----------+ 
| 2 | ARPANET | subClassof | Network | 
+-------+------------+-------------+-----------+ 
| 3 | Network | subClassof | Main  | 
+-------+------------+-------------+-----------+ 
| 5 | Software | subclassof | Main  | 
+-------+------------+-------------+-----------+ 
| 7 | Linux  | subClassof | Software | 
+-------+------------+-------------+-----------+ 
| 8 | Windows | subClassof | Software | 
+-------+------------+-------------+-----------+ 
| 12 | XP   | subClassof | Windows | 
+-------+------------+-------------+-----------+ 
| 13 | Win7  | subClassof | Windows | 
+-------+------------+-------------+-----------+ 
| 14 | Win8  | subClassof | Windows | 
+-------+------------+-------------+-----------+ 

Для предиката subClassof он будет иметь вид дерева, как это:

Main 
    |__ Network 
    |   |__ ATM 
    |   |__ ARPANET 
    | 
    |__ Software 
       |__ Linux 
       |__ Windows 
         |__ XP 
         |__ Win7 
         |__ Win8 

I хотите создать форму, которая может выбрать начальный узел и получить для него всех родителей. Например, выбирая Win7 я хочу получить:

main, Software, Windows,Win7


Шаг2: есть ли способ, чтобы напечатать это узлы с простым текстом, как это:

Main 
    |__ Software 
       |__ Windows 
         |__ Win7 

ответ

9

Ваши данные могут быть представлены в RDF как data.n3:

@prefix : <http://example.org/> . 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 

:Network rdfs:subClassOf :Main . 

:ATM rdfs:subClassOf :Network . 
:ARPANET rdfs:subClassOf :Network . 

:Software rdfs:subClassOf :Main . 

:Linux rdfs:subClassOf :Software . 
:Windows rdfs:subClassOf :Software . 

:XP rdfs:subClassOf :Windows . 
:Win7 rdfs:subClassOf :Windows . 
:Win8 rdfs:subClassOf :Windows . 

Отсюда вам просто нужен запрос SPARQL, который находит все вещи, связанные с определенным классом, путем пути (включая пустой путь) объектов rdfs:subClassOf.

prefix : <http://example.org/> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> 

select ?superclass where { 
    :Win7 rdfs:subClassOf* ?superclass 
} 
-------------- 
| superclass | 
============== 
| :Win7  | 
| :Windows | 
| :Software | 
| :Main  | 
-------------- 

Результаты в этом запросе не обязательно упорядочены по их положению в пути (хотя и в этом случае они, случается). Если вам не нужно их в порядке, вы можете сделать это (который основан на this answer about computing the position of elements in an RDF list):

prefix : <http://example.org/> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> 

select ?class where { 
    :Win7 rdfs:subClassOf* ?mid . 
    ?mid rdfs:subClassOf* ?class . 
} 
group by ?class 
order by count(?mid) 

Это находит каждый предок ?class из :Win7, а также каждый ?mid промежуточного предка. Для предка ?class расстояние вычисляется как число промежуточных отношений между (count(?mid)). Он заказывает результаты на основе этого расстояния, поэтому :Win7 является ближайшим предком, :Windows после этого и так далее.

Вы можете даже сделать некоторые фантазии форматирования вы хотите, как это:

prefix : <http://example.org/> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> 

select (group_concat(?name ; separator="--") as ?path) where { 
    { 
    select ?name where { 
     :Win7 rdfs:subClassOf* ?mid . 
     ?mid rdfs:subClassOf* ?class . 
     bind(strAfter(str(?class), "http://example.org/") as ?name) 
    } 
    group by ?class ?name 
    order by count(?mid) 
    } 
} 
----------------------------------- 
| path       | 
=================================== 
| "Win7--Windows--Software--Main" | 
----------------------------------- 

Это может можно сделать некоторые любитель обработки строк и получить многострочную строку. Вы можете посмотреть на последнюю часть this answer, где есть какое-то причудливое форматирование для хорошо выровненной матрицы для идей.

+0

Большой Как для последней части вашего ответа '... in progress ...'. :) и спасибо за правильный ответ. проголосовали и приняли, я больше не могу! – osyan

+2

Ну, в конце концов, все еще идет. :) Теперь, когда я думаю об этом, может не быть _too_ трудно получить красиво отформатированную многострочную строку. Я могу обновить позже ... –

+0

Еще раз спасибо за ваше обновление. хороший :) – osyan

Смежные вопросы