2012-07-10 32 views
7

मेरे पास एक स्पार्कल क्वेरी है जो डुप्लीकेट देता है, और मैं इसे केवल मूल्यों (विषय आईडी) में से एक पर साफ़ करना चाहता हूं। DISTINCT के विपरीत जो पैरामीटर में से केवल एक के बजाय चुने गए मानों के संयोजन के लिए एक अद्वितीय मान पाता है। मैंने किसी को यहां समूह का प्रस्ताव दिया है, लेकिन यह केवल तब लागू होता है जब मैं समूह के बाद सभी पैरामीटर सूचीबद्ध करता हूं (मेरा स्पार्कल एंडपॉइंट शिकायत करता है, उदाहरण के लिए चयन में गैर-समूह कुंजी चर:? व्यवसाय)। मैंने एक आंतरिक चयन चलाने की कोशिश की, लेकिन यह इस विशिष्ट क्वेरी के लिए काम नहीं कर रहा है। तो सवाल स्वयं के साथ एक मुद्दा हो सकता है (liveInIn वैकल्पिक के मान डुप्लिकेट होने लगते हैं)?स्पैर्कल कुंजी बनाम अलग-अलग मान

SPARQL के साथ सीखने की अवस्था में प्रारंभिक डीबी के साथ पर्याप्त खुश होने के बावजूद, अन्यथा अनियमित के लिए स्पष्ट व्याख्या करने के लिए स्वतंत्र महसूस करें! :)

select distinct 
    ?subjectID ?englishName ?sex ?locatedIn15Name 
    ?dob ?dod ?dom ?bornLocationName ?occupation 
    where { 
     ?person a hc:Person ; 
     hc:englishName ?englishName ; 
     hc:sex ?sex; 
     hc:subjectID ?subjectID; 
     optional { ?person hc:livedIn11 ?livedIn11 . 
      ?livedIn11 hc:englishName ?lived11LocationName . 
      ?livedIn11 hc:locatedIn11 ?locatedIn11 . 
      ?locatedIn11 hc:englishName ?locatedIn11Name . 
      ?locatedIn11 hc:locatedIn15 ?locatedIn15 . 
?locatedIn15 hc:englishName ?locatedIn15Name . 
} . 
     optional {?person hc:born ?dob } . 
     optional {?person hc:dateOfDeath ?dod } . 
     optional {?person hc:dateOfMarriage ?dom } . 
     optional { ?person hc:bornIn ?bornIn . 
     ?bornIn hc:englishName ?bornLocationName . 
      ?bornIn hc:easting ?easting . 
      ?bornIn hc:northing ?northing } . 
     optional { ?person hc:occupation ?occupation } 
     FILTER regex(?englishName, "^FirstName LastName") 
     } 
    GROUP BY 
    ?subjectID ?englishName ?sex 
    ?locatedIn15Name ?dob ?dod ?dom 
    ?bornLocationName ?occupation 

उत्तर

12

पुन त्रुटि संदेश: चयन में

गैर समूह कुंजी चर: कब्जे

आप SAMPLE() कुल का उपयोग करके इस से बच सकते हैं - यह आप की अनुमति देगा ?subjectID पर समूह बनाने के लिए अभी भी शेष चर के लिए मान चुनें, बशर्ते आप केवल उन अन्य चर के लिए एक मूल्य प्राप्त करने की देखभाल करें।

यहाँ इस का एक सरल उदाहरण है:

SELECT ?subjectID (SAMPLE(?dob) AS ?dateOfBirth) 
WHERE 
{ 
    ?person a hc:Person ; 
      hc:subjectID ?subjectID . 
    OPTIONAL { ?person hc:born ?dob } 
} 
GROUP BY ?subjectID 
+0

+1 (IMHO) के लिए सैंपल का बहुत ही अपरंपरागत उपयोग। –

+0

धन्यवाद रॉब, यह वास्तव में आसान है! मैं अनुमान लगा रहा हूं कि कुछ हद तक गैर-निर्धारक नमूनाकरण है, इसलिए सावधानी के साथ उपयोग किया जा सकता है? :) – Nava

+0

पीएस एक और अधिक प्रतिष्ठा अर्जित करने के बाद ऊपर उठ जाएगा। – Nava

9

नोट करने के लिए पहली बात वहाँ RDF/SPARQL में वास्तव में, एक महत्वपूर्ण जैसी कोई चीज नहीं है, है। आप एक ग्राफ से पूछताछ कर रहे हैं, और ?subjectID आपके द्वारा चुने गए अन्य चर के लिए मूल्यों के कई संभावित संयोजन हो सकते हैं। यह आपके द्वारा पूछे जा रहे ग्राफ के आकार के कारण होता है: शायद आपके व्यक्ति के पास एक से अधिक अंग्रेजी नाम हैं, या वास्तव में अन्य तरीकों से: एक ही अंग्रेजी नाम को एक से अधिक व्यक्तियों द्वारा साझा किया जा सकता है।

एक SPARQL SELECT क्वेरी एक अजीब जानवर है: यह एक ग्राफ संरचना से पूछताछ करता है लेकिन परिणाम को एक फ्लैट टेबल के रूप में प्रस्तुत करता है (तकनीकी रूप से, यह परिवर्तनीय बाइंडिंग के सेट का अनुक्रम है, लेकिन यह एक ही चीज़ के बराबर है)। डुप्लिकेट होते हैं क्योंकि ग्राफ में विभिन्न पथों का मूल रूप से पालन करके आपके चर के लिए मानों के विभिन्न संयोजन मिल सकते हैं।

तथ्य यह है कि आपको अपने परिणाम में ?subjectID के लिए डुप्लिकेट मान प्राप्त होते हैं, इसलिए यह इसलिए है क्योंकि आरडीएफ ग्राफ के दृष्टिकोण से, आपकी क्वेरी के अद्वितीय समाधान हैं। आप वास्तव में जानकारी खोने के बिना परिणाम फ़िल्टर नहीं कर सकते हैं, इसलिए आम तौर पर आपको के बारे में अधिक जानने के बिना समाधान देना मुश्किल है, जो 'डुप्लिकेट' जिन्हें आप त्यागना चाहते हैं: क्या आप केवल प्रत्येक विषय के लिए एक संभावित अंग्रेजी नाम चाहते हैं, या जन्म की एक संभावित तिथि (भले ही आपके डेटा में एक से अधिक हो)?

हालांकि, यहां से निपटने/procesing इस तरह के परिणाम और अधिक आसानी से के लिए कुछ सुझाव हैं:

सबसे पहले, आप अपने ?subjectID चर पर एक ORDER BY खंड का उपयोग करने के लिए चुन सकते हैं। यह आपको ?subjectID के लिए एक ही मान के साथ कई पंक्तियां देगा, लेकिन वे सभी क्रम में होंगे, ताकि आप अपने परिणाम को और अधिक कुशलता से संसाधित कर सकें।

एक और समाधान आपकी क्वेरी को दो में विभाजित करना है: पहली क्वेरी करें कि केवल सभी अद्वितीय विषयों का चयन करता है (और संभवतः सभी अन्य मूल्य जिन्हें आप जानते हैं, पहले से ही, वे विषय को अद्वितीय मानेंगे) फिर परिणाम पर पुन: प्रयास करें और प्रत्येक व्यक्तिगत विषय आईडी के लिए में रुचि रखने वाले अन्य मूल्यों को प्राप्त करने के लिए एक अलग क्वेरी करें। यह समाधान पाखंडी की तरह लग सकता है (विशेष रूप से यदि आप एक एसक्यूएल पृष्ठभूमि से हैं), लेकिन यह वास्तव में एक बड़ी क्वेरी में सबकुछ करने की कोशिश करने से तेज़ और आसान हो सकता है।

फिर भी एक और समाधान रोब द्वारा सुझाया गया एक है: एक विशेष चर पर एक SAMPLE कुल योग (यादृच्छिक) अद्वितीय मूल्य का चयन करने के लिए। उस पर एक भिन्नता GROUP_CONCAT कुल का उपयोग करना है, जो एक ही स्ट्रिंग में सभी संभावित मानों को संयोजित करके एक एकल मूल्य बनाता है।

+0

वाह, धन्यवाद, यह बेहद सहायक है। मैंने आपके उत्तर को बहुत कुछ पढ़ा है। जब तक मैं इंतजार कर रहा था, मैंने वास्तव में थोड़ा सा प्रतिक्रिया दी और क्वेरी को दो में विभाजित कर दिया। यह मेरी दक्षता की भावना के खिलाफ चला जाता है, लेकिन यह एक साफ और सरल समाधान है। मैंने एसक्यूएल में कभी भी 'GROUP_CONCAT' का उपयोग नहीं किया है, लेकिन मूल रूप से यह फ्लैट ग्राफ़ संरचना के साथ क्या करता है इसके बारे में मेरे प्रश्न को हल करता है। मेरा अगला सवाल, पहले से ही खाली हो गया! (रोब के साथ, जब मैं थोड़ी अधिक प्रतिष्ठा अर्जित करता हूं तो पालन करने के लिए ऊपर की ओर) – Nava