3 回答

TA貢獻2003條經驗 獲得超2個贊
純SPARQL 1.1解決方案
我擴展了數據以使問題變得更難。讓我們在列表中添加一個重復元素,例如,:a最后添加一個元素:
@prefix : <http://example.org#> .
:ls :list (:a :b :c :a) .
然后我們可以使用這樣的查詢來提取每個列表節點(及其元素)以及列表中節點的位置。我們的想法是,我們可以匹配列表中的所有單個節點[] :list/rdf:rest* ?node。但是,每個節點的位置是列表頭部之間的中間節點的數量?node。我們可以通過將模式分解為來匹配每個中間節點
[] :list/rdf:rest* ?mid . ?mid rdf:rest* :node .
然后,如果我們分組?node,則不同?mid綁定的數量是?node列表中的位置。因此,我們可以使用以下查詢(它還抓取rdf:first與每個節點關聯的元素)來獲取列表中元素的位置:
prefix : <https://stackoverflow.com/q/17523804/1281433/>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select ?element (count(?mid)-1 as ?position) where {
[] :list/rdf:rest* ?mid . ?mid rdf:rest* ?node .
?node rdf:first ?element .
}
group by ?node ?element
----------------------
| element | position |
======================
| :a | 0 |
| :b | 1 |
| :c | 2 |
| :a | 3 |
----------------------
這是有效的,因為RDF列表的結構是這樣的鏈接列表(其中?head是列表的開頭(對象:list),并且是?mid因為模式的另一個綁定[] :list/rdf:rest* ?mid):
RDF列表的圖形表示
與Jena ARQ擴展的比較
該問題的提問者還發布了一個使用Jena的ARQ擴展來處理RDF列表的答案。該答案中公布的解決方案是
PREFIX : <http://example.org#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX list: <http://jena.hpl.hp.com/ARQ/list#>
SELECT ?elem ?pos WHERE {
?x :list ?ls .
?ls list:index (?pos ?elem).
}
這個答案取決于使用Jena的ARQ和啟用擴展,但它更簡潔和透明。不明顯的是一個人是否有明顯更好的表現。事實證明,對小名單,差別不是特別顯著,但對于大名單中,ARQ擴展有很多更好的性能。純SPARQL查詢的運行時間變得非常長,而使用ARQ擴展的版本幾乎沒有差異。
-------------------------------------------
| num elements | pure SPARQL | list:index |
===========================================
| 50 | 1.1s | 0.8s |
| 100 | 1.5s | 0.8s |
| 150 | 2.5s | 0.8s |
| 200 | 4.8s | 0.8s |
| 250 | 9.7s | 0.8s |
-------------------------------------------
這些具體值明顯會因您的設置而異,但總體趨勢應該可以在任何地方觀察到。由于將來可能會發生變化,這里是我正在使用的ARQ的特定版本:
$ arq --version
Jena: VERSION: 2.10.0
Jena: BUILD_DATE: 2013-02-20T12:04:26+0000
ARQ: VERSION: 2.10.0
ARQ: BUILD_DATE: 2013-02-20T12:04:26+0000
因此,如果我知道我必須處理非平凡大小的列表并且我有ARQ可用,我會使用擴展名。

TA貢獻1815條經驗 獲得超10個贊
簡短的回答
不是沒有超出標準,除非你的名單長度有限,那么你可以做一些像臟的事情:
{ ?x :list (:a) BIND(1 AS ?length) }UNION{ ?x :list ([], :a) BIND(2 AS ?length) }UNION{ ?x :list ([], [], :a) BIND(3 AS ?length) }...
等等
某些RDF查詢引擎具有可在RDF列表上運行的非標準功能,但您必須查閱系統的文檔。
答案很長
這是RDF列表的一個癥狀,具有可怕的結構和定義。不知何故,我們最終得到了兩種表示列表的方式,這兩種方式都很難用!
如果您控制數據,請使用更合理的表示,例如
<x> :member [ rdf:value :a ; :ordinal 1 ;], [ rdf:value :b ; :ordinal 2 ;], [ rdf:value :c ; :ordinal 3 ;]...
然后你可以查詢:
{ <x> :member [ rdf:value :a ; :ordinal ?position ] }
添加回答
舉報