2013-08-02 5 views
5

में सभी चरणों को ढूंढना मैं SPARQL के लिए नया हूं और मैं एक संपत्ति पथ क्वेरी बनाने की कोशिश कर रहा हूं जो पथ के साथ प्रत्येक मध्यवर्ती चरण को थूक देगा। अब तक मैं इस है:संपत्ति पथ

select ?object 
where { 
    <subjectURI> <isRelatedTo>+ ?object . 
} 

यह मुझे मेरे विषय पथ भर यूआरआई के लिए सभी संबंधों की एक सूची प्रदान करती है, चाहे कितना दूर से संबंध (मुझे ठीक कर लें मैं अब तक गलत हूँ)।

लेकिन, मैं देखना चाहता हूं कि संबंध कैसे व्यवस्थित होते हैं। कुछ ऐसा:

<subjectURI> <isRelatedTo> <object1> 
<object1> <isRelatedTo> <object2> 
<object2> <isRelatedTo> <object3> 

और इसी तरह ... क्या यह संभव है?

+0

बस इसके लिए अधिसूचना देखी, क्षमा करें! मैंने नीचे दी गई टिप्पणियों में से कोई प्रगति नहीं की है। इस समय परियोजना चालू है, लेकिन मुझे जल्द ही वापस आने की उम्मीद है! – bdkauff

उत्तर

2

नहीं, यह संपत्ति पथों के डिजाइन की एक सीमा है।

पथों का उपयोग या तो अधिक जटिल क्वेरी पैटर्न को कॉम्पैक्ट करने के लिए किया जा सकता है या इनका उपयोग आपके उदाहरण के रूप में मनमाने ढंग से लंबाई पथों के परीक्षण के लिए किया जा सकता है।

पूर्व को एक ऐसे रूप में परिवर्तित किया जा सकता है जो आपको मध्यवर्ती चरणों जैसे उदा।

SELECT * WHERE 
{ 
    ?s <http://predicate>/<http://predicate> ?o 
} 

निम्नलिखित करने के लिए परिवर्तित किया जा सकता है:

SELECT * WHERE 
{ 
    ?s <http://predicate> ?intermediate . 
    ?intermediate <http://predicate> ?o . 
} 

दुर्भाग्य से एक ही मनमाने ढंग से लंबाई पथ के लिए नहीं किया जा सकता। लेकिन अगर आप जानते हैं कि रास्तों पर ऊपरी बाध्य कर रहे हैं आप तो जैसे आपकी क्वेरी पुनर्लेखन कर सकते हैं:

SELECT * 
WHERE 
{ 
    { 
    ?s <http://predicate> ?step1 . 
    ?step1 <http://predicate> ?o . 
    } 
    UNION 
    { 
    ?s <http://predicate> ?step1 . 
    ?step1 <http://predicate> ?step2 . 
    ?step2 <http://predicate> ?o . 
    } 
    # Add additional UNION for each length of path you want up to your upper bound 
} 

हालांकि आप तुरंत देख सकते हैं के रूप में इस बातें बहुत वर्बोज़ बनाता है।

+0

धन्यवाद! मुझे लगता है कि मुझे इस सीमा के बारे में पढ़ना याद है। समाधान वर्बोज़ है, लेकिन होप्स पोस्ट-क्वेरी को पुनर्निर्माण करने की कोशिश करने से शायद कम है। – bdkauff

+1

@ user2350906 हालांकि संपत्ति पथों के साथ आप क्या कर सकते हैं, इसके बारे में कुछ सीमाएं हैं, मुझे लगता है कि आप ऐसी जानकारी प्राप्त कर सकते हैं जिसे आप किसी क्वेरी से ढूंढ रहे हैं जो संपत्ति पथ का उपयोग करता है, और मैंने इसे [उत्तर] में वर्णित किया है (http://stackoverflow.com/a/18032019/1281433)। –

4

जबकि some limitations आपकी संपत्ति आवश्यकताओं के आधार पर क्या कर सकते हैं, आपकी सटीक आवश्यकताओं के आधार पर, आप यहां जो चाहिए उसे प्राप्त करने में सक्षम हो सकते हैं। इस डेटा पर विचार करें:

@prefix : <urn:ex:>. 

:a :relatedTo :b . 
:b :relatedTo :c . 
:c :relatedTo :d . 

:a :relatedTo :e . 
:e :relatedTo :f . 
:f :relatedTo :g . 

:h :relatedTo :i . 
:i :relatedTo :j . 
:j :relatedTo :k . 
:k :relatedTo :l . 

जिसमें तीन :relatedTo रास्ते हैं:

a --> b --> c --> d 
a --> e --> f --> g 
h --> i --> j --> k --> l 

मुझे लगता है कि आपके मामले में, आप एक विशिष्ट विषय था, लेकिन हम एक छोटा सा सामान्यीकरण कर सकते हैं और के लिए पूछना इस तरह एक प्रश्न के साथ इन रास्तों में से प्रत्येक में एक किनारे:

prefix : <urn:ex:> 
select * where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
order by ?start ?end 

$ arq --data data.n3 --query query.sparql 
----------------------------- 
| begin | midI | midJ | end | 
============================= 
| :a | :a | :b | :d | 
| :a | :b | :c | :d | 
| :a | :c | :d | :d | 
| :a | :a | :e | :g | 
| :a | :e | :f | :g | 
| :a | :f | :g | :g | 
| :h | :h | :i | :l | 
| :h | :i | :j | :l | 
| :h | :j | :k | :l | 
| :h | :k | :l | :l | 
----------------------------- 

जो प्रत्येक :relatedTo पथ के प्रत्येक किनारे को दिखाता है।आप उत्पादन एक छोटा सा खूबसूरत भी बना सकता है:

prefix : <urn:ex:> 
select (concat(str(?begin),"--",str(?end)) as ?path) ?midI ?midJ where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
order by ?path 

$ arq --data data.n3 --query query.sparql 
-------------------------------------- 
| path     | midI | midJ | 
====================================== 
| "urn:ex:a--urn:ex:d" | :a | :b | 
| "urn:ex:a--urn:ex:d" | :b | :c | 
| "urn:ex:a--urn:ex:d" | :c | :d | 
| "urn:ex:a--urn:ex:g" | :a | :e | 
| "urn:ex:a--urn:ex:g" | :e | :f | 
| "urn:ex:a--urn:ex:g" | :f | :g | 
| "urn:ex:h--urn:ex:l" | :h | :i | 
| "urn:ex:h--urn:ex:l" | :i | :j | 
| "urn:ex:h--urn:ex:l" | :j | :k | 
| "urn:ex:h--urn:ex:l" | :k | :l | 
-------------------------------------- 

यह वही दृष्टिकोण आप यह जानने की तरह कुछ रोचक बातें करते हैं कितनी दूर अलग कुछ नोड्स हैं जाएगा:

prefix : <urn:ex:> 
select ?begin ?end (count(*) as ?length) where { 
    # start a path 
    ?begin :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    # grab next edge 
    ?midI :relatedTo ?midJ . 

    # get to the end of the path. 
    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end 

------------------------ 
| begin | end | length | 
======================== 
| :a | :g | 3  | 
| :a | :d | 3  | 
| :h | :l | 4  | 
------------------------ 

ऊपर दिए गए डेटा में, पथ वर्णानुक्रम में होते हैं और इसलिए सॉर्टिंग किनारों को सही क्रम में उत्पन्न करती है। हालांकि, भले ही किनारे नोड्स वर्णानुक्रम में नहीं हैं, फिर भी हम सूची में अपनी स्थिति की गणना करके उन्हें प्रिंट कर सकते हैं। इस क्वेरी:

prefix : <urn:ex:> 
select ?begin ?midI ?midJ (count(?counter) as ?position) ?end where { 
    ?begin :relatedTo* ?counter . 
    ?counter :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    ?midI :relatedTo ?midJ . 

    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end ?midI ?midJ 

---------------------------------- 
| begin | midI | midJ | .1 | end | 
================================== 
| :a | :a | :b | 1 | :d | 
| :a | :b | :c | 2 | :d | 
| :a | :c | :d | 3 | :d | 
| :a | :a | :e | 1 | :g | 
| :a | :e | :f | 2 | :g | 
| :a | :f | :g | 3 | :g | 
| :h | :h | :i | 1 | :l | 
| :h | :i | :j | 2 | :l | 
| :h | :j | :k | 3 | :l | 
| :h | :k | :l | 4 | :l | 
---------------------------------- 

हम नहीं आवश्यक जरूरत करने के लिए कि गिनती देखते हैं, लेकिन आप के बजाय स्थिति का चयन करने के लिए, आप इसे एक छँटाई शर्त के रूप में इस्तेमाल कर सकते हैं कर सकते हैं:

prefix : <urn:ex:> 
select ?begin ?midI ?midJ ?end 
where { 
    ?begin :relatedTo* ?counter . 
    ?counter :relatedTo* ?midI . 
    FILTER NOT EXISTS { [] :relatedTo ?begin } 

    ?midI :relatedTo ?midJ . 

    ?midJ :relatedTo* ?end . 
    FILTER NOT EXISTS { ?end :relatedTo [] } 
} 
group by ?begin ?end ?midI ?midJ 
order by ?begin ?end count(?counter) 

और अनुक्रम में अपने किनारों को प्राप्त करने की गारंटी दीजिये।

+0

प्रतिक्रिया के लिए धन्यवाद। आप जो सुझाव देते हैं वह एक बिंदु तक काम करता है, लेकिन जैसा कि मैं कुछ चरणों से अधिक जोड़ता हूं, क्वेरी कुछ भी नहीं देती है। इस प्रश्न के अनुसार: 'चयन करें? X (COUNT (? Z) AS? LinkTotal) जहां { ? X: relatedTo +? Z। } ? एक्स होने से समूह (COUNT (? एक्स)> 1) ' मैं 12 वर्ष की एक अधिकतम मूल्य इसका मतलब यह नहीं है कि लंबे समय तक कम से कम पथ 12 कदम दूर है मिलता है, और इसलिए मैं सक्षम होना चाहिए 12 (गलती, 10?) इंटरमीडिएट चरणों को अपनी क्वेरी में जोड़ने के लिए और अभी भी एक मिलान केस प्राप्त करें? – bdkauff

+0

@ user2350906 अपना डेटा देखे बिना, यह बताना मुश्किल है कि क्वेरी क्या बदलेगी। हालांकि मुझे नोटिस है कि आप '+' का उपयोग कर रहे हैं, जिसका मैंने किसी भी प्रश्न में उपयोग नहीं किया था। '+' का मतलब एक या अधिक है, जबकि '*' 0 या अधिक है। –

+0

@ user2350906 क्या आप इस पर और विस्तार कर सकते हैं? '+' के बीच का अंतर महत्वपूर्ण है, और यदि आप '? X' द्वारा समूहित कर रहे हैं, तो क्या 'हैविंग' क्लॉज होना चाहिए (COUNT (? X)> 1)' 'NAVING COUNT (? X)> 1) '(यानी, गिनती '? Z', नहीं'? Y')? –

संबंधित मुद्दे