{"id":20950413,"url":"https://github.com/atomgraph/ltlod","last_synced_at":"2026-03-16T12:38:24.203Z","repository":{"id":6451695,"uuid":"7691258","full_name":"AtomGraph/LTLOD","owner":"AtomGraph","description":"Lithuanian Linked Open Data","archived":false,"fork":false,"pushed_at":"2022-08-09T08:08:23.000Z","size":45721,"stargazers_count":8,"open_issues_count":0,"forks_count":5,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-01-19T22:40:52.873Z","etag":null,"topics":["knowledge-graph","linked-open-data","linkeddata","lithuania","open-data","rdf","sparql","vocabulary"],"latest_commit_sha":null,"homepage":"","language":"XSLT","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AtomGraph.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-18T17:49:35.000Z","updated_at":"2022-08-09T14:10:36.000Z","dependencies_parsed_at":"2022-09-03T00:33:12.705Z","dependency_job_id":null,"html_url":"https://github.com/AtomGraph/LTLOD","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtomGraph%2FLTLOD","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtomGraph%2FLTLOD/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtomGraph%2FLTLOD/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AtomGraph%2FLTLOD/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AtomGraph","download_url":"https://codeload.github.com/AtomGraph/LTLOD/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243345875,"owners_count":20275906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["knowledge-graph","linked-open-data","linkeddata","lithuania","open-data","rdf","sparql","vocabulary"],"created_at":"2024-11-19T00:48:25.423Z","updated_at":"2025-12-26T12:39:02.160Z","avatar_url":"https://github.com/AtomGraph.png","language":"XSLT","funding_links":[],"categories":[],"sub_categories":[],"readme":"LTLOD projektą sukūrėme prieš daugiau nei 5 metus. Deja, nei Linked Open Data, nei Open Data situacija apskritai per tą laiką iš esmės nepagerėjo. Užbuksavome ties [3 žvaigždute](https://5stardata.info/en/).\n\nŽiūrint atgal, mūsų Linked Data [specifikacijos](../../wiki) greičiausiai buvo per daug techniškos ir nieko nesakančios žmonėms, nesusipažinusiems su RDF standartais.\nDabar norime šią klaidą ištaisyti ir palaipsniui išaiškinti, kaip RDF ir Linked Data yra sukuriami, naudojami ir kaip sukuria vertę.\n\n# Grafo duomenų modelis\n\nSu duomenimis dirbantys programuotojai, mokslininkai ir t.t. dažniausiai yra susipažinę su reliaciniu duomenų modeliu, kitaip sakant, lentelėmis. Pavyzdžiui:\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eID\u003c/th\u003e\n            \u003cth\u003eVardas\u003c/th\u003e\n            \u003cth\u003eMokykla\u003c/th\u003e\n            \u003cth\u003eKlasė\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003e1\u003c/td\u003e\n            \u003ctd\u003ePetriukas\u003c/td\u003e\n            \u003ctd\u003eFabijoniškių\u003c/td\u003e\n            \u003ctd\u003e3B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003e2\u003c/td\u003e\n            \u003ctd\u003eMarytė\u003c/td\u003e\n            \u003ctd\u003eStanevičiaus\u003c/td\u003e\n            \u003ctd\u003e2C\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\nBet kuri lentelė gali būti atvaizduota grafo pavidalu:\n\n![Lentelė grafo pavidalu](../../raw/master/lentele.png)\n\n`ID1`, `ID2` ir t.t. unikaliai identifikuoja kiekvieną įrašą.\n\n## Entity-Attribute-Value\n\nDabar tokią grafo struktūrą galima užrašyti kaip lentelę, bet kita forma:\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eĮrašas\u003c/th\u003e\n            \u003cth\u003eSavybė\u003c/th\u003e\n            \u003cth\u003eReikšmė\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID1\u003c/td\u003e\n            \u003ctd\u003eID\u003c/td\u003e\n            \u003ctd\u003e1\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID1\u003c/td\u003e\n            \u003ctd\u003eVardas\u003c/td\u003e\n            \u003ctd\u003ePetriukas\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID1\u003c/td\u003e\n            \u003ctd\u003eMokykla\u003c/td\u003e\n            \u003ctd\u003eFabijoniškių\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID1\u003c/td\u003e\n            \u003ctd\u003eKlasė\u003c/td\u003e\n            \u003ctd\u003e3B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID2\u003c/td\u003e\n            \u003ctd\u003eID\u003c/td\u003e\n            \u003ctd\u003e2\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID2\u003c/td\u003e\n            \u003ctd\u003eMarytė\u003c/td\u003e\n            \u003ctd\u003eVardas\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID2\u003c/td\u003e\n            \u003ctd\u003eMokykla\u003c/td\u003e\n            \u003ctd\u003eStanevičiaus\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003eID2\u003c/td\u003e\n            \u003ctd\u003eKlasė\u003c/td\u003e\n            \u003ctd\u003e2C\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\nGavome ne ką kitą, kaip [Entity-Atttribute-Value](https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model) duomenų modelį. \n\nEAV \"ištraukia\" kiekvieną stulpelio/reikšmės sąryšį iš mūsų pradinės reliacinės lentelės ir pateikia jį kaip atskirą įrašą. Dėl to ši EAV lentelė turi 8 eilutes: 2 eilutės * 4 stulpeliai pradinėjė lentelėje lygu 8.\n\n_Nepaisant to, kiek stulpelių yra reliacinėje lentelėje, ją visada galima transformuoti į grafo pavidalą bei EAV lentelę su 3 stulpeliais._ Tai tiesiog skirtingi to pačio duomenų rinkinio pavidalai.\n\n# RDF duomenų modelis\n\n[RDF (Resource Description Framework)](https://www.w3.org/TR/rdf11-primer/) yra W3C specifikacija, kuri standartizuoja grafo/EAV pavidalo duomenis ir pritaiko juos publikavimui internete.\n\nVietoje Entity-Attribute-Value, RDF modelyje ta pati 3 stulpelių lentelė vadinama Subject-Property-Object. Kiekvienas jos įrašas yra vadinamas \"[triple](https://www.w3.org/TR/rdf11-primer/#section-triple)\".\n\nVienas kertinių RDF \"akmenų\" yra globalūs URI identifikatoriai. Jie leidžia vienareikšmiškai identifikuoti resursus pasaulinio interneto mastu.\nPalyginimui, reliacinėse DB identifikatoriai (paprastai ID stulpelių reikšmės) yra lokalios toms duomenų bazėms ir neturi prasmės globaliame kontekste.\n\nURI naudojami ne tik įrašams, bet ir savybėms (properties) bei tipams (classes) identifikuoti. Dėl to RDF savybės gali būti lengvai perpanaudojamos skirtinguose duomenų rinkiniuose.\n\nDabar galime patobulinti mūsų EAV pavyzdį, paversdami įrašų ID bei savybes į atitinkamus URI, panaudodami `https://atviras.vilnius.lt/mokiniai/` adresą kaip pagrindą (tuo pačiu savybes pervadinsime angliškai):\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eSubject\u003c/th\u003e\n            \u003cth\u003eProperty\u003c/th\u003e\n            \u003cth\u003eObject\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/1\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id\u003c/td\u003e\n            \u003ctd\u003e1\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/1\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/name\u003c/td\u003e\n            \u003ctd\u003ePetriukas\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/1\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/school\u003c/td\u003e\n            \u003ctd\u003eFabijoniškių\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/1\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/class\u003c/td\u003e\n            \u003ctd\u003e3B\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/2\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id\u003c/td\u003e\n            \u003ctd\u003e2\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/2\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/name\u003c/td\u003e\n            \u003ctd\u003eMarytė\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/2\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/school\u003c/td\u003e\n            \u003ctd\u003eStanevičiaus\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/2\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/class\u003c/td\u003e\n            \u003ctd\u003e2C\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\nTurėdami tokią struktūrą, galime lengvai pridėti naujus ryšius į mūsų grafą. Pavyzdžiui, draugystės ryšius:\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003eSubject\u003c/th\u003e\n            \u003cth\u003eProperty\u003c/th\u003e\n            \u003cth\u003eObject\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/1\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/friendsWith\u003c/td\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokiniai/id/2\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\nTokie ryšiai reikalautų papildomų lentelių reliacinėje DB. Reliacinio modelio schemos nelankstumas yra vienas didžiausių minusų, palyginus su RDF duomenų bazėmis ([triplestores](https://en.wikipedia.org/wiki/Triplestore)), kuriuose schema nėra būtina.\n\n_Dėl stabilios Subject-Property-Object struktūros, fiziniame lygmenyje RDF duomenų rinkiniai integruojami juos tiesiog sujungiant, kas nieko nekainuoja._ Su reliacinėmis lentelėmis tai tiesiog neįmanoma.\n\n_RDF yra (kryptinio) grafo duomenų modelis, o ne duomenų formatas_. RDF gali būti užrašytas skirtingais formatais naudojant [skirtingas sintakses](https://www.w3.org/TR/rdf11-primer/#section-graph-syntax): plain-text ([Turtle](https://www.w3.org/TR/turtle/)), XML ([RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/)), JSON ([JSON-LD](https://www.w3.org/TR/json-ld11/)) ir t.t. RDF bibliotekos dažniausiai palaiko daugumą standartinių RDF sintaksių.\n\n# Linked (Open) Data\n\n[Linked Data (LD)](https://en.wikipedia.org/wiki/Linked_data), arba Linked Open Data (LOD), priklausomai nuo duomenų atvirumo, yra RDF duomenų publikavimo internete metodas.\n\nPrincipas labai paprastas: HTTP protokolu iškvietę bet kurį URI, panaudotą RDF rinkinyje, turėtume gauti triples apie tuo URI identifikuotą objektą. Pavyzdžiui, užklauskime Linked Data serverio duomenų apie Petriuką tekstiniu RDF formatu Turtle:\n\n    GET https://atviras.vilnius.lt/mokiniai/id/1\n    Accept: text/turtle\n\n    200 OK\n    Content-Type: text/turtle\n\n    @prefix mok: \u003chttps://atviras.vilnius.lt/mokiniai/\u003e .\n\n    \u003chttps://atviras.vilnius.lt/mokiniai/id/1\u003e mok:id 1 ;\n        mok:name \"Petriukas\" ;\n        mok:school \"Fabijoniškių\" ;\n        mok:class \"3B\" ;\n        mok:friendsWith \u003chttps://atviras.vilnius.lt/mokiniai/id/2\u003e .\n\nGauname serverio atsaką su struktūrizuotais machine-readable duomenimis apie konkretų mus dominantį objektą, šiuo atveju mokinį.\n\nLinked Data metodo galia atsiskleidžia, kai RDF duomenyse naudojamos ne ID ar pavadinimų reikšmės, identifikuojančios susijusius objektus, bet tiesioginė nuoroda į to objekto URI.\nPavyzdžiui, vietoje `\"Fabijoniškių\"` kaip tekstinės reikšmės mokyklai identifikuoti, suteikime mokykloms savus URI adresus, pvz. naudojant jų kodus: `https://atviras.vilnius.lt/mokyklos/190003851`.\n\nPatobulintas Linked Data atsakas atrodo taip:\n\n```turtle\n@prefix mok: \u003chttps://atviras.vilnius.lt/mokiniai/\u003e .\n\n\u003chttps://atviras.vilnius.lt/mokiniai/id/1\u003e mok:id 1 ;\n    mok:name \"Petriukas\" ;\n    mok:school \u003chttps://atviras.vilnius.lt/mokyklos/190003851\u003e ;\n    mok:class \"3B\" ;\n    mok:friendsWith \u003chttps://atviras.vilnius.lt/mokiniai/id/2\u003e .\n```\n\nDabar programinė įranga gali naviguoti URI adresais ir užklausti serverio dominančių objektų duomenų, lygiai kaip mes naviguojame interneto puslapius naudodami nuorodas.\n\nGalutinis RDF grafas atrodo taip:\n\n![RDF grafas](../../raw/master/mokiniai.png)\n\n## SPARQL\n\n[SPARQL](https://www.w3.org/TR/sparql11-overview/) yra RDF užklausų kalba. Analogiškai, kaip SQL yra RDBMS užklausų kalba, tik SPARQL specifikacija žymiai trumpesnė už SQL. Dauguma RDF triplestores palaiko SPARQL 1.1 ir neišradinėja savo dialektų, dėl to užklausos labai portabilios.\n\nTurėdami mūsų pavyzdinį RDF duomenų rinkinį, galėtume suformuluoti užklausą, kuri atsakytų, kokių mokyklų mokiniai turi daugiausiai draugų:\n\n```sparql\nPREFIX mok: \u003chttps://atviras.vilnius.lt/mokiniai/\u003e\n\nSELECT ?school (COUNT(?friend) AS ?friendCount)\n{\n    ?person mok:friendsWith ?friend ;\n        mok:school ?school .\n}\nGROUP BY ?school\nORDER BY DESC(?friendCount)\n```\n\n# Knowledge Graph nauda\n\nPastaruoju metu Linked Data marketingistų vadinama _Knowledge Graph_, tai nuo šiol vadinkime ir mes taip. (Ar reikėtų rašyti _Žinių grafas_?)\n\nKam Knowledge Graphs naudojami? Kokia iš jų nauda (atviriesiems duomenims)?\n\nNe paslaptis, kad atvirieji duomenis turi būti lengvai integruojami ir perpanaudojami. _RDF Knowledge Graph yra vienintelis standartizuotas metodas, leidžiantis sujungti atskirus duomenų rinkinius į vientisą, potencialiai beribį sluoksnį._ Neišradinėkime dviračio, jis jau išrastas. Bet kokios lokalaus ar nacionalinio masto specifikacijos, portalai ar manifestai, ignoruojantys RDF ir Knowledge Graphs, bus tik pinigų ir laiko švaistymas.\n\nKam mums vientisas sluoksnis? Kad naudotumėme resursus išmintingai, sluoksniuodami vienas pastangas ant kitų, naudodami vienų darbo vaisius kaip pagrindą kitiems darbams. Duomenų rinkinio vertė auga [proporcingai ryšių jame skaičiui](https://en.wikipedia.org/wiki/Network_effect).\n\nTai nėra tik mūsų išmislas. Galbūt įtikinti padės autoritetingi leidiniai:\n* Financial Times. [Governments fail to capitalise on swaths of open data](https://www.ft.com/content/f8e9c2ea-b29b-11e8-87e0-d84e0d934341)\n* Forbes. [Is The Enterprise Knowledge Graph Finally Going To Make All Data Usable?](https://www.forbes.com/sites/danwoods/2018/09/19/is-the-enterprise-knowledge-graph-going-to-finally-make-all-data-usable/)\n\n\u003e The knowledge graph is the only currently implementable and sustainable way for businesses to move to the higher level of integration needed to make data truly useful for a business.\n\n## Pritaikymo pavyzdys\n\nTarkime, norime sudaryti Vilniaus mokiniams naują pietų racioną. Nesvarbu, ar tai idėja hakatone, ar komercinis projektas įmonėje. Mums reikia mokinių ir mokyklų sąrašo patiekalų meniu sudarymui (kalorijų apskaičiavimams ar pan.) Turime 2 įgyvendinimo variantus:\n1. parsisiųsti mokinių ir mokyklų CSV, sukišti į savo reliacinę DB ar kitokias duomenų struktūras, atlikti skaičiavimus. Galbūt papublikuoti rezultatus kaip CSV.\n2. paversti savo duomenis į RDF, naudojant `atviras.vilnius.lt` URI ryšiams su mokyklomis ir mokiniais nurodyti\n\nPirmo varianto išdava: buvo 2 paskiri, tarpusavyje nesuintegruoti CSV failai, tapo 3.\n\nAntro varianto išdava: lietuviškas Knowledge Graph pasitarnavo kaip pagrindas naujam RDF rinkiniui, ir to pasekoje išsipletė.\n\nSkirtumą tikiuosi patys matote. Nenaudojant Knowledge Graph, su kiekvienu tokiu pavyzdžiu parandama vis daugiau duomenų perpanaudojimo potencialo.\n\n## Įgyvendinimas praktikoje\n\n\"Na gerai, tai darykim lietuvišką Knowledge Graph!\", jau galvojate tikriausiai. Bet kaip?! Ar tai nereikalauja kosminių semantinių technologijų su nesuvokiamais pavadinimais kaip \"ontologija\" ar \"taksonomija\"? Ar nesvietiškai brangios programinės įrangos ir panašiai?\n\nViskas yra žymiai paprasčiau. Turint duomenis CSV formatu, tereikia vienos SPARQL užklausos, kuri transformuos visą CSV rinkinį į RDF grafą. Turint XML duomenis, analogiškai gali būti pritaikytos [XSLT transformacijos](https://www.w3.org/TR/xslt/all/) konvertavimui į RDF/XML formatą.\n\nPavyzdžiui panaudokime realius Vilniaus savivaldybės duomenis: CSV su duomenimis apie [mokinius](https://github.com/vilnius/mokyklos/raw/master/Mokiniai.csv) ir [mokyklas](https://github.com/vilnius/mokyklos/raw/master/data/Mokyklu_sarasas.csv). Taipogi panaudosim tuos pačius URI adresus iš aukščiau pateiktų pavyzdžių, kombinuojant \"savadarbius\" `mok:` terminus su [schema.org](https://schema.org) savybėmis (interneto paieškos varikliai, tokie kaip Google ir Bing, [indeksuoja struktūrizuotus duomenis su schema.org terminais](https://developers.google.com/search/docs/guides/intro-structured-data)). Konvertavimą atliksime naudodami [CSV2RDF](https://github.com/AtomGraph/CSV2RDF) atviro kodo biblioteką.\n\n### Mokiniai\n\nTransformacijos (kai kur vadinama \"mapping\") užklausa:\n\n```sparql\nPREFIX mok:     \u003chttps://atviras.vilnius.lt/mokiniai/\u003e\nPREFIX schema:  \u003chttps://schema.org/\u003e\nPREFIX xsd:     \u003chttp://www.w3.org/2001/XMLSchema#\u003e\n\nCONSTRUCT\n{\n    ?pupil a schema:Person ;\n        mok:id ?id ;\n        schema:identifier ?id ;\n        schema:birthDate ?birth_date ; \n        mok:class ?class ;\n        mok:school ?school ;\n        schema:affiliation ?school .\n}\nWHERE\n{\n    ?pupil_row \u003c#MokinioID\u003e ?id ;\n        \u003c#GimimoData\u003e ?birth_date_string ;\n        \u003c#KlasesPavadinimas\u003e ?class ;\n        \u003c#IstaigosKodas\u003e ?school_code .\n\n    BIND(uri(concat(str(\u003cmokiniai/\u003e), encode_for_uri(?id))) AS ?pupil)\n    BIND(xsd:date(?birth_date_string) AS ?birth_date)\n    BIND(uri(concat(str(\u003cmokyklos/\u003e), encode_for_uri(?school_code))) AS ?school)\n}\n```\n\nPaleidžiame CSV2RDF naudodami shell komandą, kuri paima CSV tiesiai iš GitHub ir transformuoja (šiuo atveju nurodome `tab` kaip reikšmių skirtuką, nes toks naudojamas `Mokiniai.csv` faile):\n\n    curl -s https://raw.githubusercontent.com/vilnius/mokyklos/master/Mokiniai.csv -o Mokiniai.csv ; cat Mokiniai.csv | java -jar csv2rdf-1.0.0-SNAPSHOT-jar-with-dependencies.jar https://atviras.vilnius.lt/ Mokiniai.rq $'\\t' \u003e Mokiniai.nt    \n\nGauname 442310 triples [N-Triples](https://www.w3.org/TR/n-triples/) formatu. Vieną CSV eilutę atitinka 7 RDF triples (tiek, kiek suformavome užklausos `CONSTRUCT` dalyje):\n\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://schema.org/affiliation\u003e \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://atviras.vilnius.lt/mokiniai/school\u003e \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://atviras.vilnius.lt/mokiniai/class\u003e \"8a\" .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://schema.org/birthDate\u003e \"2002-06-06\"^^\u003chttp://www.w3.org/2001/XMLSchema#date\u003e .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://schema.org/identifier\u003e \"9166267\" .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttps://atviras.vilnius.lt/mokiniai/id\u003e \"9166267\" .\n    \u003chttps://atviras.vilnius.lt/mokiniai/9166267\u003e \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type\u003e \u003chttps://schema.org/Person\u003e .\n\n### Mokyklos\n\nTransformacijos užklausa:\n\n```sparql\nPREFIX schema:     \u003chttps://schema.org/\u003e \n\nCONSTRUCT\n{\n    ?school a schema:School ;\n        schema:name ?name ;\n        schema:identifier ?code ;\n        schema:address ?address ;\n        schema:telephone ?telephone ;\n        a [ schema:name ?type ] ;\n        schema:email ?email .\n}\nWHERE\n{\n    ?school_row \u003c#name\u003e ?name ;\n        \u003c#code\u003e ?code ;\n        \u003c#address\u003e ?address ;\n        \u003c#tel\u003e ?telephone_string ;\n        \u003c#type\u003e ?type ;\n        \u003c#email\u003e ?email_string .\n\n    BIND(uri(concat(str(\u003cmokyklos/\u003e), encode_for_uri(?code))) AS ?school)\n    BIND(concat(\"+\", ?telephone_string) AS ?telephone)\n    BIND(uri(concat(\"mailto:\", ?email_string)) AS ?email)\n}\n```\n\nKomanda (reikšmių skirtukas `;`):\n\n    curl -s https://raw.githubusercontent.com/vilnius/mokyklos/master/data/Mokyklu_sarasas.csv -o Mokyklu_sarasas.csv ; cat Mokyklu_sarasas.csv | java -jar csv2rdf-1.0.0-SNAPSHOT-jar-with-dependencies.jar https://atviras.vilnius.lt/ Mokyklu_sarasas.rq ';' \u003e Mokyklu_sarasas.nt\n\nGauname 984 triples, arba po 8 triples iš kiekvienos CSV eilutės:\n\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttps://schema.org/email\u003e \u003cmailto:rastine@ateities.vilnius.lm.lt\u003e .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type\u003e _:BX2D7b9d6c03X3A16833b6771fX3AX2D7ffd .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttps://schema.org/telephone\u003e \"+37052478447\" .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttps://schema.org/address\u003e \"Vilniaus m. sav. Vilniaus m. S. Stanevičiaus g. 98\" .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttps://schema.org/identifier\u003e \"190003666\" .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttps://schema.org/name\u003e \"Vilniaus Ateities mokykla\" .\n    \u003chttps://atviras.vilnius.lt/mokyklos/190003666\u003e \u003chttp://www.w3.org/1999/02/22-rdf-syntax-ns#type\u003e \u003chttps://schema.org/School\u003e .\n    _:BX2D7b9d6c03X3A16833b6771fX3AX2D7ffd \u003chttps://schema.org/name\u003e \"Pagrindinė mokykla\" .\n\n### Duomenų sujungimas\n\nMokyklų kodai - raktas ([foreign key](https://en.wikipedia.org/wiki/Foreign_key)) tarp lentelių `Mokiniai` (stulpelio `IstaigosKodas`) ir `Mokyklu_sarasas` (stulpelio `code`). Transformavimo užklausos pasirūpina, kad abejais atvejais iš mokyklų kodų (pvz. kaip `190003666`) būtų sugeneruojami vienodi URL, pvz. `https://atviras.vilnius.lt/mokyklos/190003666`. Tai mūsų sukurti globalūs Vilniaus mokyklų identifikatoriai.\n\nDabar tiesiog sumetame abu `Mokiniai.nt` ir `Mokyklu_sarasas.nt` į triplestore, tokią kaip Apache Jena [Fuseki](https://jena.apache.org/documentation/fuseki2/) ar [Dydra](https://dydra.com), ir viskas. _RDF magija įvyko._ Vientisame, bendrame Knowledge Graph'e turime 443293 triples, kitaip sakant [\"datapoints\"](https://en.wikipedia.org/wiki/Unit_of_observation), apie Vilniaus mokyklas ir mokinius. Tai atlikti ir tuo pačiu rašyti šį tekstą užtruko porą valandų.\n\nDeja (?), neturime duomenų apie mokinių draugystės ryšius, dėl to nėra prasmės vykdyti SPARQL užklausą [iš pavyzdžio](#sparql). Tačiau galima gauti atsakymų į kitus klausimus. Pavyzdžiui, koks vidutinis mokinių amžius kiekvienoje mokykloje, surūšiuotas nuo didžiausio?\n\n```sparql\nPREFIX xsd:     \u003chttp://www.w3.org/2001/XMLSchema#\u003e\nPREFIX schema:  \u003chttps://schema.org/\u003e \n\nSELECT ?school (SAMPLE(?schoolName) AS ?schoolNameSample) (AVG(?age) / xsd:dayTimeDuration(\"P365D\") AS ?avgAge)\n{\n    ?pupil schema:affiliation ?school ;\n        schema:birthDate ?birthDate .\n    ?school schema:name ?schoolName .\n    BIND (xsd:date(NOW()) - ?birthDate AS ?age)\n}\nGROUP BY ?school\nORDER BY DESC (?avgAge)\n```\n\nRezultatai \"šokiruoja\": jauniausi mokiniai [Vilniaus Vilkpėdės darželyje-mokykloje](http://www.vilkpedes.lt) (vidutiniškai 7 metų), vyriausi -- [Vilniaus Gabrielės Petkevičaitės-Bitės suaugusiųjų mokymo centre](http://www.gpbite.eu) (vidutiniškai 41+ metų).\n\n\u003ctable\u003e\n    \u003cthead\u003e\n        \u003ctr\u003e\n            \u003cth\u003e\u003ccode\u003e?school\u003c/code\u003e\u003c/th\u003e\n            \u003cth\u003e\u003ccode\u003e?schoolNameSample\u003c/code\u003e\u003c/th\u003e\n            \u003cth\u003e\u003ccode\u003e?avgAge\u003c/code\u003e\u003c/th\u003e\n        \u003c/tr\u003e\n    \u003c/thead\u003e\n    \u003ctbody\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/291710460\u003c/td\u003e\n            \u003ctd\u003eVilniaus Gabrielės Petkevičaitės-Bitės suaugusiųjų mokymo centras\u003c/td\u003e\n            \u003ctd\u003e41.446445\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/190009548\u003c/td\u003e\n            \u003ctd\u003eVilniaus suaugusiųjų mokymo centras\u003c/td\u003e\n            \u003ctd\u003e34.39103\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/190009733\u003c/td\u003e\n            \u003ctd\u003eVilniaus Židinio suaugusiųjų gimnazija\u003c/td\u003e\n            \u003ctd\u003e28.863071\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003e...\u003c/td\u003e\n            \u003ctd\u003e...\u003c/td\u003e\n            \u003ctd\u003e...\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/191713046\u003c/td\u003e\n            \u003ctd\u003eVilniaus Volungės darželis-mokykla\u003c/td\u003e\n            \u003ctd\u003e8.066992\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/190022061\u003c/td\u003e\n            \u003ctd\u003eVilniaus darželis - mokykla Saulutė\u003c/td\u003e\n            \u003ctd\u003e7.9250603\u003c/td\u003e\n        \u003c/tr\u003e\n        \u003ctr\u003e\n            \u003ctd\u003ehttps://atviras.vilnius.lt/mokyklos/190016699\u003c/td\u003e\n            \u003ctd\u003eVilniaus Vilkpėdės darželis-mokykla\u003c/td\u003e\n            \u003ctd\u003e6.999386\u003c/td\u003e\n        \u003c/tr\u003e\n    \u003c/tbody\u003e\n\u003c/table\u003e\n\nJeigu turėjome hipotezę apie darželius vs. suaugusiųjų centrus, dabar galime ją pagrįsti faktais.\n\n**[Išbandykite SPARQL užklausą patys](http://atomgraph.dydra.com/ltlod/vilnius/@query#vidutinis-mokiniu-amzius-mokyklose)**\n\nVilniaus savivaldybei norint paviešinti šiuos duomenis Linked Data principų, tereikia po `atviras.vilnius.lt` URL adresu sukonfiguruoti Linked Data serverį ir prijungti jį prie triplestore. Mes jų siūlome net keletą (visi atviro kodo): nuo paprasto [`Core`](https://github.com/AtomGraph/Core) iki pilno [`Web-Node`](https://github.com/AtomGraph/Web-Node), kuriame integruotas ir HTML UI.\n\n## Reziumuojant\n\nŠis pavyzdys su mokiniais ir mokyklomis trivialus. RDF gali aprašyti viską nuo [molekulių](https://www.ebi.ac.uk/rdf/) iki [zodiako ženklų](http://data.totl.net/zodiac/), o didžiausi grafai (dauguma iš jų [atviri](https://lod-cloud.net/)) siekia dešimtis milijardų triples.\n\nLietuvos mastu galima būtų pradėti kukliau, iš pradžių imtis transformuoti mažai besikeičiančius duomenis. Kai kuriems tipams/klasėms, pvz. asmenims, organizacijoms, departamentams mes jau esame paruošę [schemas](../../wiki). Taip pat sudarėme AD aktualių [RDF standartų sąrašą](../../wiki/RDF-standartai).\n\n[IPVK](https://ivpk.lrv.lt/) už mus Knowledge Graph nepadarys. Greičiau Vilnius metro atidarys. Jeigu norim progreso, turim daryti mes _patys_, Atvirų Duomenų bendruomenė. _Bendradarbiaudami_, išnaudodami standartus ir open-source programinę įrangą.\n\n![Do it!](https://media.giphy.com/media/3o85xtLX7zCyeeWGLC/giphy.gif)\n\nSusidomėjote Knowledge Graph technologija? Norite išmokti daugiau ar turite idėjų pritaikymui? Užmeskit akį į [mūsų projektus](https://atomgraph.com/cases/) ir brūkštelkit [emailą](mailto:martynas@atomgraph.com).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomgraph%2Fltlod","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fatomgraph%2Fltlod","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fatomgraph%2Fltlod/lists"}