Otonashi meets im@sparql

Otonashi meets im@sparql

アイマスハッカソン2019 in 名古屋のLT会資料です
https://imas.connpass.com/event/123253/

Otonashi: https://github.com/subroh0508/otonashi

7c3b3366947123ba6772698b09edf4e2?s=128

subroh_0508

April 21, 2019
Tweet

Transcript

  1. 0UPOBTIJNFFUTJN!TQBSRM ʹ͜͠Γ͞ͿΖʙ!TVCSPI@

  2. ࣗݾ঺հ w ʹ͜͠Γ͞ͿΖʙ w גࣜձࣾ#FBS5BJM w "OESPJEΤϯδχΞ ,PUMJO+BWB ˑ w

    8FCΤϯδχΞ 3BJMT3FBDU  w ୲౰଎ਫ૗ɾࡾๆ݁՚ 5XJUUFS*%!TVCSPI@
  3. ϓνใࠂ w খௗ͞Μͱ%SPJE,BJHJొஃ͠·ͨ͠ 4QFL .PDL, +B$P$PͰ ΠέͯΔ6OJU5FTU؀ڥΛखʹೖΕΖ

  4. ໨࣍ ʮ0UPOBTIJʯͷػೳ঺հ w ,PUMJO੡41"32-ΫϥΠΞϯτ w ੡࡞ͷϞνϕʔγϣϯ ݐલຊԻ  σϞɾ࢖͍ํ ͜Ε͔Βͷ໺๬

  5. 0UPOBTIJ w ,PUMJO੡41"32-ΫϥΠΞϯτ w (JUIVCTVCSPIPUPOBTIJ w ػೳ w 41"32-༻ͷΫΤϦϏϧμʔ w

    ޠኮิ׬ w +40/ܗࣜͷϨεϙϯεύʔαʔ
  6. 0WFSWJFX w ࡾๆ݁՚ͷσʔλΛશͯऔͬͯ͘ΔΫΤϦ SELECT ?predicate ?object WHERE { ?idol_iri rdf:type

    imas:Idol; schema:name ?idol_name. filter( contains(?idol_name, "三峰") ) ?idol_iri ?predicate ?object } client.where { v("idol_iri") be { rdfP.type to imasC.idol and schemaP.name to v("idol_name") } filter { contains(v("idol_name"), "三峰") } v("idol_iri") be { v("predicate") to v("object") } }.select { + v("predicate") + v("object") } ੜΫΤϦ 0UPOBTIJ
  7. 0WFSWJFX w ࡾๆ݁՚ͷσʔλΛશͯऔͬͯ͘ΔΫΤϦ SELECT ?predicate ?object WHERE { ?idol_iri rdf:type

    imas:Idol; schema:name ?idol_name. filter( contains(?idol_name, "三峰") ) ?idol_iri ?predicate ?object } client.where { v("idol_iri") be { rdfP.type to imasC.idol and schemaP.name to v("idol_name") } filter { contains(v("idol_name"), "三峰") } v("idol_iri") be { v("predicate") to v("object") } }.select { + v("predicate") + v("object") } ੜΫΤϦ 0UPOBTIJ
  8. 0WFSWJFX w ࡾๆ݁՚ͷσʔλΛશͯऔͬͯ͘ΔΫΤϦ SELECT ?predicate ?object WHERE { ?idol_iri rdf:type

    imas:Idol; schema:name ?idol_name. filter( contains(?idol_name, "三峰") ) ?idol_iri ?predicate ?object } client.where { v("idol_iri") be { rdfP.type to imasC.idol and schemaP.name to v("idol_name") } filter { contains(v("idol_name"), "三峰") } v("idol_iri") be { v("predicate") to v("object") } }.select { + v("predicate") + v("object") } ੜΫΤϦ 0UPOBTIJ
  9. 0WFSWJFX w ίʔσΟϯάσϞ

  10. Ϟνϕʔγϣϯ ݐલ w ઌߦϥΠϒϥϦ"QBDIF+FOB w جຊతʹԿͰ΋Ͱ͖Δ w "32ˠΫΤϦΤϯδϯ w 41"32-ͷจ๏࢓༷ʹ४ڌ

    w JN!TQBSRMͰ΋ར༻ ਺ϲ݄લͷ΅͘ʮ͜ΕͰ͑͑΍Μʯ
  11. Ϟνϕʔγϣϯ ݐલ w "QBDIF+FOB"32ͷαϯϓϧίʔυ 5SJQMFܕΠϯελϯεΛ࡞ͬͯ #MPDLΛද͢Πϯελϯεʹ BEE5SJQMF͢Δ ΅͘ʮ͏ʔΜѹ౗త+BWBΈɹ௚ײత͡Όͳ͍ʯ

  12. Ϟνϕʔγϣϯ ݐલ w "OESPJEͰࢼ͠ʹ࢖͏ ʊਓਓਓਓਓਓਓਓʊ ʼɹbuild failedɹʻ ʉY^Y^Y^Y^Y^Y^Y^Y^ʉ ݁࿦ࣗ࡞͠Α͏ w

    41"32-ͷΫΤϦΛ"DUJWF3FDPSEͬΆ͍ॻ͖ຯͰॻ͚Δ w "OESPJEͰಈ͘ w ޠኮͷิ׬ػೳ͕͋Δ ผϞδϡʔϧͰఏڙ  w ·ͣ͸4FMFDUจ͚ͩͰ΋࢖͑ΔΑ͏ʹ͢Δ
  13. Ϟνϕʔγϣϯ ຊԻ w ϛϦΦϯUI#%ൃച w ಛయө૾ʹͯɺΨϛ1͔ΒΞΠυϧୡ΁ͷ՝୊ఏى w Ψϛ1ʮΞΠυϧʹͱͬͯɺ଍Γͳ͍΋ͷ͕͋Δͱࢥ͍·͢ʯ

  14. Ϟνϕʔγϣϯ ຊԻ w Ψϛ1ʮ଍Γͳ͍ϞϊɺͦΕ͸ʮ஌ੑʯͰ͢ʯ

  15. Ϟνϕʔγϣϯ ຊԻ w લఏ,PUMJOͰॻ͔Εͨʮ0UPOBTIJʯ 0UPOBTIJNBEFCZ,PUMJO  w ͜ͷϥΠϒϥϦ͸খௗ͞ΜͱಉҰͷଘࡏ w ੈքதɺ͋ΒΏΔ41"32-ΤϯυϙΠϯτ͔Β৘ใΛऔಘ

    w ࢖ΘΕΕ͹࢖ΘΕΔ΄Ͳখௗ͞Μ͸஌ੑΛ֫ಘ͍ͯ͘͠ w খௗ͞Μˠ଍Γͳ͍΋ͷ ஌ੑ Λิ͑Δ w ΅͘ˠਓྨͷӥஐͷશͯΛ֫ಘͨ͠z࠷ڧͷԻແখௗzΛҭͯΒΕΔ
  16. αϯϓϧΞϓϦͷσϞ w "OESPJEΞϓϦ https://twitter.com/subroh_0508/status/1115635445889523712

  17. αϯϓϧΞϓϦͷσϞ w αʔόʔαΠυ,PUMJO ,UPS  3FBDU 5ZQF4DSJQU https://twitter.com/subroh_0508/status/1118176150058967040

  18. ࢖͍ํ w (SBEMFͷEFQFOEFODJFTʹґଘؔ܎௥Ճ // build.gradle repositories { jcentor() } //

    app/build.gradle dependencies { implementation 'net.subroh0508.otonashi:core:${latest_version}' // additional implementation 'net.subroh0508.otonashi.vocabularies:schema:${latest_version}' implementation 'net.subroh0508.otonashi.vocabularies:foaf:${latest_version}' implementation 'net.subroh0508.otonashi.vocabularies:imasparql:${latest_version}' }
  19. ࢖͍ํ w (SBEMFͷEFQFOEFODJFTʹґଘؔ܎௥Ճ // build.gradle repositories { jcentor() } //

    app/build.gradle dependencies { implementation 'net.subroh0508.otonashi:core:${latest_version}' // additional implementation 'net.subroh0508.otonashi.vocabularies:schema:${latest_version}' implementation 'net.subroh0508.otonashi.vocabularies:foaf:${latest_version}' implementation 'net.subroh0508.otonashi.vocabularies:imasparql:${latest_version}' } ޠኮิ׬༻ϥΠϒϥϦ ඞཁʹԠͯ͡௥ه
  20. ࢖͍ํ w ΤϯυϙΠϯτɾ13&'*9ɾޠኮิ׬ΦϒδΣΫτͷࢦఆ val client: Kotori = Otonashi.Study { destination("https://sparql.crssnky.xyz/spql/imas/query")

    reminds(SchemaPrefix.SCHEMA, FoafPrefix.FOAF, ImasparqlPrefix.IMAS) buildsUp(*schemaVocabularies, *foafVocabularies, *imasparqlVocabularies) }
  21. ࢖͍ํ w ΤϯυϙΠϯτɾ13&'*9ɾޠኮิ׬ΦϒδΣΫτͷࢦఆ val client: Kotori = Otonashi.Study { destination("https://sparql.crssnky.xyz/spql/imas/query")

    reminds(SchemaPrefix.SCHEMA, FoafPrefix.FOAF, ImasparqlPrefix.IMAS) buildsUp(*schemaVocabularies, *foafVocabularies, *imasparqlVocabularies) } ΤϯυϙΠϯτࢦఆ
  22. ࢖͍ํ w ΤϯυϙΠϯτɾ13&'*9ɾޠኮิ׬ΦϒδΣΫτͷࢦఆ val client: Kotori = Otonashi.Study { destination("https://sparql.crssnky.xyz/spql/imas/query")

    reminds(SchemaPrefix.SCHEMA, FoafPrefix.FOAF, ImasparqlPrefix.IMAS) buildsUp(*schemaVocabularies, *foafVocabularies, *imasparqlVocabularies) } 13&'*9Λઃఆ ͜ͷҰߦͰҎԼͷ13&'*9͕ΫΤϦʹ௥Ճ͞ΕΔ PREFIX schema: <http://schema.org/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> PREFIX imas: <https://sparql.crssnky.xyz/imasrdf/URIs/imas-schema.ttl#>
  23. ࢖͍ํ w ΤϯυϙΠϯτɾ13&'*9ɾޠኮิ׬ΦϒδΣΫτͷࢦఆ val client: Kotori = Otonashi.Study { destination("https://sparql.crssnky.xyz/spql/imas/query")

    reminds(SchemaPrefix.SCHEMA, FoafPrefix.FOAF, ImasparqlPrefix.IMAS) buildsUp(*schemaVocabularies, *foafVocabularies, *imasparqlVocabularies) } ޠኮิ׬ΦϒδΣΫτͷࢦఆ TDIFNBPSH΍JN!TQBSRMͷ*3*ޠኮ͕ิ׬Ͱ͖ΔΑ͏ʹ͢Δॲཧ
  24. ࢖͍ํ w ΫΤϦ૊Έཱͯ+40/ͷϚοϓઌΫϥεͷએݴ client.where { v("idol_iri") be { rdfP.type to

    imasC.idol and schemaP.name to v("idol_name") } filter { contains(v("idol_name"), "三峰") } v("idol_iri") be { v("predicate") to v("object") } }.select { + v("predicate") + v("object") } @Serializable data class MitsumineResult( val predicate: String, val `object`: String ) ΫΤϦ ϚοϓઌͷσʔλΫϥε
  25. ࢖͍ํ w )551ΫϥΠΞϯτϥΠϒϥϦΛ࢖ͬͯΫΤϦΛ౤͛Δ ྫ,UPS suspend inline fun <reified T: Any>

    get(kotori: Kotori): SparqlResponse<MitsumineResult> { val ktorClient: HttpClient = ... val response = ktorClient.get<HttpResponse>(kotori.toString()) { accept(ContentType("application", "sparql-results+json")) } @UseExperimental(ImplicitReflectionSerializer::class) return Json.nonstrict.parse( SparqlResponse.serializer(MitsumineResult.serializer()), response.readText(charset = Charsets.UTF_8) ) }
  26. ࢖͍ํ w )551ΫϥΠΞϯτϥΠϒϥϦΛ࢖ͬͯΫΤϦΛ౤͛Δ ྫ,UPS suspend inline fun <reified T: Any>

    get(kotori: Kotori): SparqlResponse<MitsumineResult> { val ktorClient: HttpClient = ... val response = ktorClient.get<HttpResponse>(kotori.toString()) { accept(ContentType("application", "sparql-results+json")) } @UseExperimental(ImplicitReflectionSerializer::class) return Json.nonstrict.parse( SparqlResponse.serializer(MitsumineResult.serializer()), response.readText(charset = Charsets.UTF_8) ) } ,PUPSJUP4USJOH Ͱ ΤϯίʔυࡁΈ63-Λऔಘ
  27. ࢖͍ํ w )551ΫϥΠΞϯτϥΠϒϥϦΛ࢖ͬͯΫΤϦΛ౤͛Δ ྫ,UPS suspend inline fun <reified T: Any>

    get(kotori: Kotori): SparqlResponse<MitsumineResult> { val ktorClient: HttpClient = ... val response = ktorClient.get<HttpResponse>(kotori.toString()) { accept(ContentType("application", "sparql-results+json")) } @UseExperimental(ImplicitReflectionSerializer::class) return Json.nonstrict.parse( SparqlResponse.serializer(MitsumineResult.serializer()), response.readText(charset = Charsets.UTF_8) ) } ϦΫΤετૹ৴
  28. ࢖͍ํ w )551ΫϥΠΞϯτϥΠϒϥϦΛ࢖ͬͯΫΤϦΛ౤͛Δ ྫ,UPS suspend inline fun <reified T: Any>

    get(kotori: Kotori): SparqlResponse<MitsumineResult> { val ktorClient: HttpClient = ... val response = ktorClient.get<HttpResponse>(kotori.toString()) { accept(ContentType("application", "sparql-results+json")) } @UseExperimental(ImplicitReflectionSerializer::class) return Json.nonstrict.parse( SparqlResponse.serializer(MitsumineResult.serializer()), response.readText(charset = Charsets.UTF_8) ) } +40/ˠ.JUTVNJOF3FTVMU΁ͷม׵
  29. ͜Ε͔Βͷ໺๬ w $*Ͱςετճ͢ w 41"32-ͷݴޠ࢓༷ʹԊͬͯ࡞Γ௚͢ ಛʹ4FSWJDFߏจͷ௥Ճ  w ಈ͘͜ͱΛ࠷༏ઌʹͨͨ͠Ίɺ֤ॴΨόΨό࣮૷Ͱػೳత੍ݶ͕ଟ͍ w

    αϯϓϧΞϓϦͷ௥Ճ w ,PUMJO+4,PUMJOˠ+BWBTDSJQUͷτϥϯεύΠϧϑϨʔϜϫʔΫ w ,PUMJO/BUJWF,PUMJOͰJ04ΞϓϦ࡞ΕΔϑϨʔϜϫʔΫ ݄ͷ-5ձͰ༧ఆ͍ͯͨ͠Ϟϊ͕஻Εͳ͍৔߹͸0UPOBTIJͷৄ͍࣮͠૷ղઆ͢Δ͔΋
  30. rʮ5P1BSSBOHFECZTVCSPI@ʯ lͲΜͳ೔΋৐Γӽ͑ͯ ·͙ͬ͢ਐ΋͏ ΈΜͳ৴ͯ͡ ࠷ڧͷԻແখௗɺ஀ੜͷॠؒ·Ͱz (JWFNFB4UBS 8FMDPNF$POUSJCVUFTˠTVCSPIPUPOBTIJ