2012-03-20 19 views
11

शायद इसका उत्तर देने में आसान है, लेकिन मैं यह भी पता नहीं लगा सकता कि इसे खोजने के लिए Google क्वेरी को कैसे तैयार किया जाए।SPARQL निर्माण क्वेरी में रिक्त नोड्स को फिर से विस्तारित करने के लिए कैसे?

मैं एक डेटासेट के खिलाफ SPARQL निर्माण क्वेरी लिख रहा हूं जिसमें रिक्त नोड्स शामिल हैं। अगर मैं

CONSTRUCT {?x ?y ?z .} WHERE {?x ?y ?z .}

की तरह एक प्रश्न करना तब मेरे परिणामों में से एक हो सकता है तो:

nm:John nm:owns _:Node

कौन सा एक समस्या है अगर

_:Node nm:has nm:Hats

के सभी ट्रिपल किसी भी तरह से क्वेरी परिणाम में नहीं पहुंचते हैं (क्योंकि कुछ पार्सर्स जो मैं rdf की तरह उपयोग कर रहा हूं पायथन के लिए lib वास्तव में bnodes dangling पसंद नहीं है)।

क्या मेरे मूल CONSTRUCT क्वेरी को किसी भी बीएनओडी परिणामों से जुड़े सभी ट्रिपल को दोबारा जोड़ने के लिए लिखने का कोई तरीका है, जैसे कि मेरे नए ग्राफ में कोई बोनोड लटक नहीं रहा है?

+2

आप एक तरह से जहां एक निर्माण क्वेरी चलाने और फिर चला सकते हैं कि के खिलाफ एक SPARQL क्वेरी में यह कर रहे हैं, तो आप वास्तव में * कर सकते हैं * एक संक्षिप्त-घिरा विवरण (सीबीडी) SPARQL प्रश्नों का उपयोग कर मिलता है। [त्रिभुज क्वेरी को दोबारा वापस करने के लिए स्पैक्ल प्रश्न पूछें जो एक rdfs बनाते हैं: कक्षा परिभाषा] (http://answers.semanticweb.com/questions/26220/sparql-query-to-return-all-triples-recursively- that-make-up-an-rdfsclass-definition) (और हो सकता है [SPARQL में संक्षेप में संक्षिप्त विवरण लागू करें] (http://answers.semanticweb.com/questions/20361/implementing-concise-bounded-description-in-sparql))। –

+1

पिछली टिप्पणी में उत्तरों के पीछे विचार यह है कि आप एक * नई संपत्ति * बना सकते हैं जो प्रभावी रूप से संपत्ति पथ के भीतर भविष्यवाणी के रूप में कार्य करता है। उदाहरण के लिए, प्रत्येक आईआरआई नोड I के लिए, आप एक तिहाई "मैं selfIRI i" जोड़ते हैं। फिर जब आप "? X p/selfIRI? Y" जैसे पथ लिखते हैं, तो आपने यह सुनिश्चित किया है कि y एक आईआरआई नोड है। –

उत्तर

10

रिकर्सन संभव नहीं है। निकटतम मैं सोच सकता हूं कि SPARQL 1.1 property paths (नोट: वह संस्करण पुराना है) लेकिन बोनोड परीक्षण उपलब्ध नहीं हैं (afaik)।

तुम बस अनुगामी bnodes साथ बयान को दूर कर सकते हैं:

CONSTRUCT {?x ?y ?z .} WHERE 
{ 
    ?x ?y ?z . 
    FILTER (!isBlank(?z)) 
} 

या अपनी किस्मत अगले बिट प्राप्त करने में कठिनाई का प्रयास करें:

CONSTRUCT {?x ?y ?z . ?z ?w ?v } WHERE 
{ 
    ?x ?y ?z . 
    OPTIONAL { 
    ?z ?w ?v 
    FILTER (isBlank(?z) && !isBlank(?v)) 
    } 
} 

(है कि पिछले क्वेरी सुंदर दंडित है, Btw)

आप DESCRIBE के साथ बेहतर हो सकते हैं, जो अक्सर बोनोड छोड़ देंगे।

+0

धन्यवाद उपयोगकर्ता। मेरी वर्तमान योजना दो गहराई तक रिकर्सन के बारे में चिंता किए बिना दो स्तर की क्वेरी का उपयोग करती है। IsBlank फ़िल्टर मदद कर सकता है, लेकिन फ़िल्टर वास्तव में कत्ल प्रदर्शन का प्रतीत होता है क्योंकि SPARQL फ़िल्टर लाइन-दर-लाइन करने से पहले पूरे प्री-फ़िल्टर सबग्राफ को भौतिक रूप से पूरा कर रहा है। तो जब तक कि unfiltered सबग्राफ छोटा न हो, फिल्टर प्रश्न वास्तव में गहन होने लगते हैं। – rogueleaderr

+2

आप यह नहीं कह सकते कि "SPARQL पूरे प्री-फ़िल्टर सबग्राफ को भौतिक बना रहा है ...": विभिन्न SPARQL इंजन कार्यान्वयन में अलग-अलग शक्तियों और कमजोरियों के साथ अलग-अलग एल्गोरिदम होंगे। यह आपके द्वारा उपयोग की जा रही लाइब्रेरी के संस्करण के आधार पर भी भिन्न होता है। –

3

उपयोगकर्ता 205512 सुझाव देता है कि, उस पकड़ को दोबारा पकड़ना संभव नहीं है, और जैसा कि वे इंगित करते हैं, नोड्स प्राप्त करने वाले आपके डेटा में मनमानी स्तरों को नीचे जाने के लिए वैकल्पिक (ओं) का उपयोग करके, गैर-तुच्छ आकार वाले डेटाबेस पर कुछ भी संभव नहीं है।

बोनोड स्वयं स्थानीय स्तर पर स्केल किए गए हैं, परिणाम सेट पर, या फ़ाइल में। इस बात की कोई गारंटी नहीं है कि एक बीएनओडी आपको पार्सिंग से मिलता है या परिणाम सेट से एक ही आईडी है जो डेटाबेस में उपयोग की जाती है (हालांकि कुछ डेटाबेस क्वेरी परिणामों के लिए इसकी गारंटी देते हैं)। इसके अलावा, "चयन? एस" जैसे प्रश्न {? S? P _: bnodeid1} "जैसा है" चुनें? कहां {? एस? पी? ओ} "- ध्यान दें कि उस मामले में बोनोड को चर के रूप में माना जाता है , "चीज w/id 'bnodeid1' ​​के रूप में नहीं" डिजाइन के इस quirk bnodes के लिए क्वेरी करना मुश्किल बनाता है, इसलिए यदि आप डेटा के नियंत्रण में हैं, तो मैं उनका उपयोग न करने का सुझाव दूंगा। सामानों के नाम उत्पन्न करना मुश्किल नहीं है जो अन्यथा बीएनओडी होंगी, और नामित संसाधन v। Bnodes क्वेरीिंग के दौरान ओवरहेड नहीं बढ़ाएंगे।

इससे आपको रिकर्स करने और डेटा को पकड़ने में मदद नहीं मिलती है, लेकिन इसके लिए, मैं ऐसे सामान्य प्रश्नों की सिफारिश करने की अनुशंसा नहीं करता; वे अच्छी तरह से स्केल नहीं करते हैं और आमतौर पर आप चाहते हैं या जरूरत से अधिक वापस आते हैं। मैं सुझाव दूंगा कि आप अधिक निर्देशित प्रश्न पूछें। आपकी मूल निर्माण क्वेरी पूरे डेटाबेस की सामग्री को नीचे खींच लेगी, जो आम तौर पर आप जो चाहते हैं वह नहीं है।

आखिरकार, वर्णन उपयोगी हो सकता है, मानक कार्यान्वयन नहीं है; SPARQL spec किसी विशेष व्यवहार को परिभाषित नहीं करता है, इसलिए यह जो भी देता है वह डेटाबेस विक्रेता को छोड़ दिया जाता है, और यह अलग हो सकता है। यदि आप अपने आवेदन के साथ विभिन्न डेटाबेस की कोशिश करने की योजना बनाते हैं तो यह आपके कोड को कम पोर्टेबल बना सकता है। यदि आप वर्णन से बाहर एक विशिष्ट व्यवहार चाहते हैं, तो आप इसे स्वयं लागू करने के लिए सबसे अच्छे हैं। संसाधन के लिए संक्षिप्त बाध्य वर्णन की तरह कुछ करना कोड का एक आसान टुकड़ा है, हालांकि आप बोनोड के आस-पास कुछ सिरदर्द में भाग सकते हैं।

+1

उत्तर माइकल के लिए धन्यवाद। मेरा उदाहरण क्वेरी थोड़ा अपरिहार्य था ... जो मैं वास्तव में करने की कोशिश कर रहा हूं वह एक डेटासेट में किसी दिए गए इकाई के बारे में सारी जानकारी खींचता है जिसे मैंने डाउनलोड किया है। लेकिन डेटासेट में प्रविष्टियां शामिल हैं जैसे "जॉन _: 1234 का निर्माता था"। तो मुझे लगता है कि मेरे विकल्प दो-स्तर की क्वेरी का उपयोग करना चाहते हैं और उम्मीद है कि यह प्रदर्शन को कुचलने में सक्षम नहीं है, या बस सभी बोनोड नाम देने के लिए डेटाबेस को पुन: स्थापित करें। ऐसा लगता है कि SPARQL spec इसके लिए मजबूत समर्थन का उपयोग कर सकता है, क्योंकि ऐसा प्रतीत नहीं होता है कि यह एक विशेष रूप से असामान्य मुद्दा होगा। – rogueleaderr

1

ruby ​​RDF.rb लाइब्रेरी के साथ काम करने के संबंध में, जो आरडीएफ :: ग्राफ ऑब्जेक्ट्स पर महत्वपूर्ण सुविधा विधियों के साथ SPARQL क्वेरीज की अनुमति देता है, निम्नलिखित को खाली नोड्स का विस्तार करना चाहिए।

rdf_type = RDF::SCHEMA.Person # for example 
rdf.query([nil, RDF.type, rdf_type]).each_subject do |subject| 
    g = RDF::Graph.new 
    rdf.query([subject, nil, nil]) do |s,p,o| 
    g << [s,p,o] 
    g << rdf_expand_blank_nodes(o) if o.node? 
    end 
end 

def rdf_expand_blank_nodes(object) 
    g = RDF::Graph.new 
    if object.node? 
    rdf.query([object, nil, nil]) do |s,p,o| 
     g << [s,p,o] 
     g << rdf_expand_blank_nodes(o) if o.node? 
    end 
    end 
    g 
end