2017-11-28 15 views
5

वर्तमान में मैं LDBC Benchmark के लिए SPARQL क्वेरीज़ लागू कर रहा हूं। मैं bi-read-3 क्वेरी के समाधान के साथ आया था। डेटा स्कीमा के प्रासंगिक हिस्सा है निम्नलिखित: enter image description hereक्या यह SPARQL क्वेरी सरलीकृत हो सकती है?

क्वेरी विवरण:

खोजें टैग और टैग कि दौरान इस्तेमाल किया गया है कि संदेश में दिए गए वर्ष के किसी महीने के दौरान इस्तेमाल किया गया अगले महीने। दोनों महीनों के लिए, प्रत्येक टैग का उपयोग करने वाले संदेशों की गिनती की गणना करें।

मेरे समाधान (with some syntax highlight):

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX sn: <http://www.ldbc.eu/ldbc_socialnet/1.0/data/> 
PREFIX snvoc: <http://www.ldbc.eu/ldbc_socialnet/1.0/vocabulary/> 
PREFIX sntag: <http://www.ldbc.eu/ldbc_socialnet/1.0/tag/> 
PREFIX foaf: <http://xmlns.com/foaf/0.1/> 
PREFIX dbpedia: <http://dbpedia.org/resource/> 
PREFIX dbpedia-owl: <http://dbpedia.org/ontology/> 


SELECT ?tagName (SUM(?countMonth1) as ?countMonth1) (SUM(?countMonth2) as ?countMonth2) (ABS(SUM(?countMonth1) - SUM(?countMonth2)) as ?diff) 
WHERE 
{ 
    { 
    SELECT ?tagName (COUNT(?message) as ?innerCountMonth1) 
    WHERE { 

     BIND (2010 as ?year1) . 
     BIND (9 as ?month1) . 

     { 
     ?message rdf:type snvoc:Comment 
     } UNION { 
     ?message rdf:type snvoc:Post 
     } . 
     ?message snvoc:creationDate ?creationDate . 
     FILTER ((year(?creationDate) = ?year1 && month(?creationDate) = ?month1)) 

     ?message snvoc:hasTag ?tag . 
     ?tag foaf:name ?tagName . 

    } 
    GROUP BY ?tagName 
    } UNION { 
    SELECT ?tagName (COUNT(?message) as ?innerCountMonth2) 
    WHERE { 

     BIND (2010 as ?year1) . 
     BIND (9 as ?month1) . 
     BIND (?year1 + FLOOR(?month1/12.0) as ?year2) . 
     BIND (IF (?month1 = 12, 1, ?month1 + 1) as ?month2) . 
     { 
     ?message rdf:type snvoc:Comment 
     } UNION { 
     ?message rdf:type snvoc:Post 
     } . 
     ?message snvoc:creationDate ?creationDate . 
     FILTER (year(?creationDate) = ?year2 && month(?creationDate) = ?month2) 

     ?message snvoc:hasTag ?tag . 
     ?tag foaf:name ?tagName . 

    } 
    GROUP BY ?tagName 
    } 

    BIND (COALESCE(?innerCountMonth1, 0) as ?countMonth1) 
    BIND (COALESCE(?innerCountMonth2, 0) as ?countMonth2) 
} 
GROUP BY ?tagName 
ORDER BY DESC(?diff) ?tagName 

मुझे लगता है एक सरल समाधान है कि वहाँ है, लेकिन मैं यह समझ नहीं कर सकते हैं।

मेरा प्रश्न यह है कि: यह प्रश्न एक सरल/अधिक प्रभावी तरीके से कार्यान्वित किया जा सकता है? उदा। नेस्टेड प्रश्नों के बिना या बस एक तेज़ तरीका।

मैं वास्तव में SPARQL में नया हूं, इसलिए मैं हर उपयोगी टिप्पणी या सुधार की सराहना करता हूं।

उत्तर

1
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> 
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> 
PREFIX snvoc: <http://www.ldbc.eu/ldbc_socialnet/1.0/vocabulary/> 
PREFIX foaf: <http://xmlns.com/foaf/0.1/> 

SELECT 
?tagName 
(SUM(xsd:integer(?isFirst)) AS ?countMonth1) 
(SUM(xsd:integer(?isSecond)) AS ?countMonth2) 
(ABS(?countMonth1 - ?countMonth2) AS ?diff) 
WHERE 
    { 
    VALUES (?year1 ?month1) {(2010 9)} 
    VALUES (?type) {(snvoc:Comment) (snvoc:Post)} 
    ?message a ?type; snvoc:hasTag/foaf:name ?tagName; snvoc:creationDate ?creationDate . 
    BIND (year(?creationDate) AS ?year) . 
    BIND (month(?creationDate) AS ?month) . 
    BIND (IF (?month1 = 12, ?year1 + 1, ?year1 ) AS ?year2) . 
    BIND (IF (?month1 = 12,   1, ?month1 + 1) AS ?month2) . 
    BIND (((?month1 = ?month) && (?year1 = ?year)) AS ?isFirst) . 
    BIND (((?month2 = ?month) && (?year2 = ?year)) AS ?isSecond) . 
    FILTER (?isFirst || ?isSecond) 
    } 
    GROUP BY ?tagName HAVING (bound(?tagName)) 

अपडेट

टिप्पणियाँ देखें।

+1

धन्यवाद! मुझे मामूली परिवर्तन करना पड़ा, उदाहरण के लिए: '(एबीएस (? CountMonth1 -? CountMonth2) के रूप में? Diff)' के बजाय '(एबीएस (एसयूएम (? CountMonth1) - एसयूएम (? CountMonth2)) के रूप में? Diff)', 'xsd : 'xsd: int' के बजाय पूर्णांक' और '? name'' के साथ '? name' को प्रतिस्थापित करें, लेकिन यह पूरी तरह से काम करता है। [यहां] (https://github.com/antaljanosbenjamin/ldbc_snb_implementations/blob/sparql-queires/sparql/queries/bi-3.sparql) अंतिम संस्करण है। मुझे लगता है कि अब तक यह महत्वपूर्ण नहीं है, लेकिन आप टेस्ट डेटा पा सकते हैं [यहां] (https://github.com/antaljanosbenjamin/ldbc_snb_implementations/tree/sparql-queires/sparql/test-data) –

+1

@ जैनोसबेन्जमिनएटल ओके, धन्यवाद आपको बहुत! मैंने अपना जवाब संपादित कर लिया है। साथ ही, मैंने एक छोटे डेटासेट पर क्वेरी का परीक्षण किया है, क्वेरी ठीक दिखती है (यदि अलग-अलग टैग अलग-अलग नाम हैं)। बीटीडब्ल्यू, हालांकि आपको इस विशेष मामले में नेस्टेड चयन की आवश्यकता नहीं है, ब्लेज़ग्राफ तथाकथित [नामित उपक्विरी] (https://wiki.blazegraph.com/wiki/index.php/NamedSubquery) का समर्थन करता है। –

+1

नोट के लिए धन्यवाद! भविष्य में, हम शायद ब्लेज़ग्राफ का उपयोग करेंगे (वर्तमान में मैं स्टारडॉग का उपयोग कर रहा हूं), लेकिन मुझे लगता है कि प्रश्नों को केवल आधिकारिक डब्ल्यू 3 सी स्पैरक्लु मानक से विशेषताओं का उपयोग करना चाहिए। दुर्भाग्यवश, मुझे मानक में नामित सबक्वायरी सुविधा नहीं मिली। –

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