2013-08-28 23 views
2

我有一個RDF文件,我需要從中提取一些信息並將其寫入文件。我的理解它是如何工作的基本,但我堅持這一點:RDF列出主題與他們的對象在一行

String queryString = "select ?person ?children where { ?person ?hasChildren ?children}"; 
TupleQuery tupleQuery = conn.prepareTupleQuery(QueryLanguage.SPARQL, queryString); 
TupleQueryResult result = tupleQuery.evaluate();  
while (result.hasNext()) { 
    BindingSet bindingSet = result.next(); 
    Value p1 = bindingSet.getValue("person"); 
    Value p2 = bindingSet.getValue("child"); 
    println(p1 + " has children " + p2 +""); 
} 
result.close(); 

我得到的輸出是這樣的:

http://example.org/people/person1 has children http://example.org/people/child1 
http://example.org/people/person1 has children http://example.org/people/child2 

我怎麼沒看到列出所有的人與他們的此格式的對象:

person1 has children child1 and child2 

這怎麼辦?

+1

這段代碼不能是你實際運行的代碼;查詢綁定變量'?children',但是您正在檢索名爲'?child'的變量的值。 –

回答

3

你會發現這個答案,它描述了SPARQL的group_concat,有用:

在SPARQL,當你有一個結果集查詢解決方案,可以group在一個或多個合併具有這些共同變量的解決方案。例如,考慮數據

@prefix : <http://example.org/people/>. 

:person1 :hasChild :child1, :child2, :child3 . 
:person2 :hasChild :child4, :child5 . 
:person3 :hasChild :child6 . 

如果您運行下面的查詢就可以了

prefix : <http://example.org/people/> 

select ?person ?child where { 
    ?person :hasChild ?child . 
} 

你得到的結果是這樣的:通過結果

$ arq --data data.n3 --query query.sparql 
---------------------- 
| person | child | 
====================== 
| :person3 | :child6 | 
| :person2 | :child5 | 
| :person2 | :child4 | 
| :person1 | :child3 | 
| :person1 | :child2 | 
| :person1 | :child1 | 
---------------------- 

迭代,你在有你問題會產生你當前得到的輸出類型。我們想要做的是真正得到這樣的結果:

$ arq --data data.n3 --query query.sparql 
---------------------------------------- 
| person | child      | 
======================================== 
| :person3 | :child6     | 
| :person2 | :child4, :child5   | 
| :person1 | :child1, :child2, :child3 | 
---------------------------------------- 

而這正是group_by讓我們做。像這樣的查詢:

prefix : <http://example.org/people/> 

select ?person (group_concat(?child;separator=' and ') as ?children) where { 
    ?person :hasChild ?child . 
} 
group by ?person 

產生(請注意,在結果的變量是?children,不?child,因爲我們使用group_concat(...) as ?children創建新的變量?children):

$ arq --data data.n3 --query query.sparql 
--------------------------------------------------------------------------------------------------------------------------- 
| person | children                          | 
=========================================================================================================================== 
| :person3 | "http://example.org/people/child6"                   | 
| :person1 | "http://example.org/people/child3 and http://example.org/people/child2 and http://example.org/people/child1" | 
| :person2 | "http://example.org/people/child5 and http://example.org/people/child4"          | 
--------------------------------------------------------------------------------------------------------------------------- 

如果您使用這樣的查詢並遍歷結果,按照你的要求打印它們,你會得到你想要的結果。如果你確實想從人和兒童身上取消領先的http://example.org/people/,你需要更多的字符串處理。例如,使用STRAFTER去除http://example.org/people/前綴,你可以使用這樣的查詢:

prefix : <http://example.org/people/> 

select 
(strafter(str(?personX),"http://example.org/people/") as ?person) 
(group_concat(strafter(str(?child),"http://example.org/people/");separator=' and ') as ?children) 
where { 
    ?personX :hasChild ?child . 
} 
group by ?personX 

得到類似的結果:

$ arq --data data.n3 --query query.sparql 
---------------------------------------------- 
| person | children      | 
============================================== 
| "person3" | "child6"      | 
| "person2" | "child5 and child4"   | 
| "person1" | "child3 and child2 and child1" | 
---------------------------------------------- 

,當你做你的打印,會給你的結果像

person3 has children child6 
person2 has children child5 and child4 
person1 has children child3 and child2 and child1 
+0

非常棒。非常感謝你。你知道在Prolog中是否有相同的group_concat&strafter? – user2598997

+0

@ user2598997在純Prolog中?或者您是否使用Prolog引擎來查詢RDF(例如,像Allego提供的內容)? –

+0

你說得對,我正在使用prog在allegrograph:(select(?person?child)(q?person!ns:childOf?child)) – user2598997

相關問題