RDFまたはSPARQLの問題点・疑問に関するポエム
背景
先日のアイマスハッカソンで某氏から、im@sparqlに関するある要望を受けた
「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」
ハッカソン当時のアイドルのインスタンスには、アイドル名がschema:nameにxml:lang="ja"として格納されていた。(今は英語名xml:lang="en"が追加されている)
<schema:name xml:lang="ja">如月千早</schema:name>
この言語タグを付けたプロパティはよくある文字列型(xsd:String)ではなく、言語タグ付き文字列型(rdf:langString)として認識される。(datatype()関数使えば分かるよ)
つまり、
select * where{ ?s ?p "如月千早". }
では検索できない。("如月千早"はxsd:Stringなため)
検索するためには、
select * where{ ?s ?p "如月千早"@ja. }
といった具合に、言語を指定してあげる必要がある。
その際、
「この@ja
って、"如月千早"が日本語タグで書かれてると知ってないと書けないよね」
と言う話になった。たしかに、実は"如月千早"が中国語として登録されていれば、日本語だと思って@ja
を付ける人は「検索にヒットしねぇ...」と呟くことになる。
そこで冒頭の
「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」
に繋がる。
select * where{ ?s ?p "如月千早"@ANY_LANGUAGE. }
のような(上記の書き方はできない)感じで検索したいということだ。
ちなみに、
select * where{ ?s ?p ?o. filter(str(?o)="如月千早") }
といった感じで、str()関数でrdf:langStringをxsd:stringに型変換してフィルタリングすると実現できる。
スマートじゃないよねって結論だけど。
疑問
SPARQL触ったことある方は、上の背景を読んだだけで「言語タグ付き文字型リテラルで検索すれば良いじゃん」と思うでしょう。
SPARQLはリテラルに^^
を付けて後ろに型を書くと、その型リテラルになる。
"hoge"^^xsd:string "--04-27"^^xsd:gMonthDay "162"^^xsd:int "162"^^xsd:float
つまり、
select * where{ ?s ?p "如月千早"^^rdf:langString. }
しかし、なぜか検索できない
調整
<schema:name xml:lang="ja">如月千早</schema:name> ↓ <schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name>
といった具合に、RDF側を調整してみることにした。言語タグ付き文字型を明示的に宣言した。
すると、
select * where{ ?s ?p "如月千早"^^rdf:langString. }
で見事、検索にヒットさせることができた。
しかし、
select * where{ ?s ?p "如月千早"@ja. }
で検索することができなくなってしまった。言語タグの情報が死んでしまった。
何故じゃ
現状(2019/4/30)
冒頭で書いたとおり、現在は
<schema:name xml:lang="ja" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">如月千早</schema:name> <schema:name xml:lang="en" rdf:datatype="http://www.w3.org/1999/02/22-rdf-syntax-ns#langString">Kisaragi Chihaya</schema:name>
のように、英語名も並んでいる。
言語タグ情報が死んでいるので、完全に並列な情報として並んでしまってる。
たぶんrdf:langStringを消すと思うけど、結局
「言語タグを持つ文字列リテラルを、どの言語かを意識することなくSPARQLのクエリに埋め込みたい」
はどうすりゃいいんでしょうね。
追記
なんか分かる所にメモりたかったもの
RDFの文字列リテラルとは一体なんなのか? #imas_hack のSlackにメモした pic.twitter.com/6bujcudMxY
— ばんじゅん🍓 (@banjun) May 2, 2019