2017-09-11 111 views
0

我已經遇到好幾次,我一直想在CONSTRUCT查詢中使用空白節點構造相同的空節點,但我需要得到都是一樣的空節點(或幾個)查詢解決方案。產生跨多個解決方案

比方說,我們在我們的數據,他們已經寫作者和圖書的清單:

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

:stephen_king a :Author ; 
     :firstName "Stephen" ; 
     :authorOf "The Shining", "Cujo". 

:stephen_hawking a :Author ; 
     :firstName "Stephen" ; 
     :authorOf "A Brief History of Time" . 

:virginia_wolf a :Author ; 
     :firstName "Virginia" ; 
     :authorOf "Mrs Dalloway" . 

例如,假設我想所有的書綁定寫作者與第一名稱Stephen到一個空白點:

PREFIX : <http://example.org#> 
CONSTRUCT { 
    [ :containsBook ?book ] 
} 
WHERE { 
    ?book ^:authorOf/:firstName "Stephen" . 
} 

將返回類似:

[ :containsBook "The Shining" ] . 
[ :containsBook "A Brief History of Time" ] . 
[ :containsBook "Cujo" ] . 

但期望的結果是:

[ :containsBook "The Shining" ; 
    :containsBook "A Brief History of Time" ; 
    :containsBook "Cujo" ] . 

有關如何實現此目的的任何想法?

+0

你的SPARQL查詢永遠無法匹配的數據......你的三倍只能從作者到圖書領導,但是從書本 – AKSW

+0

該查詢工作,三元開始您的查詢的搜索:'SELECT * WHERE { 書^:authorOf/:名字「斯蒂芬」。 BIND(B節點()AS?B節點) }',即屬性路徑是不同 – AKSW

+0

感謝。我錯過了反轉屬性的'^',查詢已經相應更新。 –

回答

0

在已經思考了一段時間,我想到了,我認爲這是一個通用的解決方案的東西。我還沒有在許多SPARQL實現上嘗試過它,所以如果您發現它不適合您,請提供反饋。基本上,在意識到我們無法對SPARQL如何處理查詢結果部分中的數據做任何事情之後,我們自然開始考慮將空白節點綁定到變量上。所以,讓我們說,我們嘗試類似:

PREFIX : <http://example.org#> 
CONSTRUCT { 
    ?bnode :containsBook ?book 
} 
WHERE { 
    ?book :hasAuthor/:firstName "Stephen" . 
    BIND(BNODE() AS ?bnode) 
} 

不,這不會工作。這是爲什麼?該查詢評估整個查詢,並且對於每個解決方案,BIND函數將被再次調用,並且我們將以不同的空白節點結束。

現在,這裏的竅門。將查詢的BIND部分放在組中。這樣一來,由於SPARQL工程變量範圍的條款的方式,我們將最終有一個加盟後的查詢進行了評估,其中?bnode部分將被調用一次:

PREFIX : <http://example.org#> 
CONSTRUCT { 
    ?bnode :containsBook ?book 
} 
WHERE { 
    ?book :hasAuthor/:firstName "Stephen" . 
    { BIND(BNODE() AS ?bnode) } 
} 

希望有人認爲這和我一樣有用。乾杯。

+1

爲什麼它的工作原理用大括號'{}'是因爲,一個表示一個基本圖形圖案,以及用於空節點的下式成立:*「當使用_形式的空節點:ABC,用於空節點的標籤被限定在基本圖形模式「。* – AKSW

+1

因此,BIND在單獨的BGP中執行一次,因此,您有一個空白節點,然後與外部BGB連接。 – AKSW

+2

或者先將'BIND'放入: '''WHERE {BINOD(BNODE()AS?bnode) ?book:hasAuthor /:firstName「Stephen」。 }'''。 使用BIND,順序確實很重要 - 它與前面的內容綁定在一起。 – AndyS