はじめてのジャパンサーチ利活用スキーマ
利活用スキーマ(RDF)の特徴
- 利活用の視点での扱いやすさを重視
- 基本的な語彙はschema.orgとジャパンサーチ独自の2つのみ
- もっとも、RDFスキーマ、OWL、SKOSは(ほぼ透明な語彙として)用いています
- これらの語彙は、
PREFIX
宣言なしにSPARQLで利用可能(chname:
などの値の名前空間も含む)
- 簡単にできることはシンプルに、必要なら複雑なクエリで掘り下げられる
- REST API的な利用も可能(後述のEasySPARQL)
- 基本的な語彙はschema.orgとジャパンサーチ独自の2つのみ
- 構造化と正規化
- 多様なデータ提供者からのデータセットを、共通の構造に変換
- どのデータセットも基本的に同様のパターンで探索可能(普通に検索すれば横断検索)
- 元のデータがフラットな構造でも、可能な場合は関連性をもたせて構造化
- たとえば「絵師」と「落款印章」を関連付ける、著者の典拠URIと責任表示を含む著者項目を合わせて処理する、など
- 「いつ」「どこ」「だれ」「なに」を中心に値を正規化し、URIを付与
- 伊勢国相可村発掘 →
place:三重
、「永仁元年十月三日」→time:1293
、"葛飾卍老人"、"北斉載斗改葛飾為一"、"画狂人北斎" →chname:葛飾北斎
- 伊勢国相可村発掘 →
- 多様なデータ提供者からのデータセットを、共通の構造に変換
- 国際標準と外部データとの連携可能性
- 正規化データをLODハブに関連付け、外部のデータとも連携できる
- 統合クエリを利用して、Europeana、DPLA、Wikidataなど世界的なデータセットとの横断検索が可能
SPARQLには詳しくないんですが…
- まずEasySPARQLを使ってみましょう
- Snorqlインターフェイスのクエリ入力欄下で検索語を入力 → クエリの雛形が得られる
- ジャパンサーチのSPARQエンドポイントの解説と見比べたりしながら、望む形に手を加える
- 結果をうまく絞り込むための工夫をしているので、雛形とするにはやや複雑(最初からエンドポイント解説を読んでいくのもOK)
- NDLラボのジャパンサーチAPIを利用したWebアプリケーション作成チュートリアル§3.1にも、EasySPARQLの雛形を元にクエリをチューニングする例あり
- REST APIとしてそのまま結果を利用しても良い
- SPARQLクエリの返り値
- JSON形式を使うのが便利。
results.bindings
内に次のような結果オブジェクトが配列として並ぶ。 { "
s
": { "type": "uri", "value
": "https://jpsearch.go.jp/data/cobas-47301" }, "label
": { "type": "literal", "value
": "富嶽三十六景" }, ... },- オブジェクトのキーがSPARQLクエリの変数、その値オブジェクトの
value
が結果値。type
はその値がURIかリテラル値かを示す - SPARQエンドポイント解説の§4.2に説明あり
- JSON形式を使うのが便利。
単純記述と構造化記述をうまく使い分ける
- 「いつ」「どこ」「だれ」は複構造で記述されている
- 値をシンプルに利用するなら単純記述クエリ
SELECT * WHERE { ?s
schema:spatial
place:三重 }
- 役割やコンテクストを加味するなら構造化記述クエリ
SELECT * WHERE { ?s
jps:
spatial [jps:value
place:三重 ;jps:relationType
role:発見.出土 ] }
正規化データと名前(グラフとテキスト)
- 正規化データとLOD
- 異なる表記の名前を可能な範囲で正規化している(北斎、葛飾卍老人、北斉載斗改葛飾為一)
- NDLAやWikidataなどのLODと
owl:sameAs
で関連付けている ?s schema:creator
/
owl:sameAs
*
chname:葛飾北斎 .- EasySPARQLで生成するクエリ(#1参照)は、この
owl:sameAs
を利用して、(ジャパンサーチ正規化名以外の)NDLAなどのURIで記述されている作者も合わせて取得
- EasySPARQLで生成するクエリ(#1参照)は、この
- グラフのつながりを利用して検索する
schema:creator
とowl:sameAs
を/
で連結した記法は、SPARQL 1.1のプロパティパス構文。JavaScriptのドット記法のように、プロパティ階層を連結して簡潔に記述できるowl:sameAs
の後に加えている*
は0回以上の繰り返し(正規表現と同様)jps:relationType
の役割もグラフの階層を利用して検索できる
- 名前を用いたクエリ
- 正規化に関わらず名前のラベル(リテラル値)を持つ
- 英語(ローマ字)表記や別名なども
schema:name
におさめている(言語タグ付き) ?s schema:creator/
schema:name
"かつしか ほくさい"@ja
- テキスト一般は
schema:description
(次頁のテキスト検索を用いる)
テキスト検索とVirtuoso
- SPARQLでの文字列検索
- 値の完全一致以外は、FILTER句を使って絞り込み検索する
- 文字列の前方一致は
strstarts()
、後方一致はstrends()
、部分一致はcontains()
関数を使う ?s schema:creator/schema:name ?name .
FILTER
(strends
(?name, "Hokusai"))- ジャパンサーチ全体で部分一致検索を行なうと非常に重いので、
rdf:type
などで先に絞り込んでからが実用的 ?s
a type:絵画
; rdfs:label ?label .FILTER
(contains
(?label, "富士山"))
- Virtuosoの独自関数
- ジャパンサーチがSPARQLエンドポイントに用いているVirtuosoは、独自のインデックスに基づくテキスト検索関数
bif:contains()
を提供する ?s rdfs:label ?label . FILTER (
bif:contains
(?label, "'
富士山'
"))- 絞り込みなしでも実用的な検索ができる(ただし日本語検索は完全ではない)
- ASCII以外の文字を検索するときは、引用符の中をさらに
'
で囲む
- ジャパンサーチがSPARQLエンドポイントに用いているVirtuosoは、独自のインデックスに基づくテキスト検索関数
緯度経度と範囲検索
- Geohash
- 利活用スキーマでは、緯度経度情報がある場合は構造化ノードに
schema:geo
を加えて記述 - さらに緯度経度をGeohashにしてjps:withinで記述しているので、範囲検索が可能
- 詳しくはエンドポイント解説の§2.2どこ:位置情報とGeohashを参照
- 利活用スキーマでは、緯度経度情報がある場合は構造化ノードに
- Virtuosoの範囲関数
- 緯度経度検索した値を
bif:st_within()
関数によって絞り込む=範囲検索 - 緯度経度は
bif:st_point()
でPOINT型に変換する(経度, 緯度の順) SELECT ?s ?label ?lat ?long WHERE { #まず位置情報を持つアイテムを取得 ?s jps:spatial/schema:geo [
schema:latitude
?lat
;schema:longitude
?long
] . #緯度が90以上だとエラーになるので絞り込む(緯度経度が逆のデータあり) FILTER(?lat < 90) #bif:st_withinによる絞り込み FILTER(bif:st_within
( bif:st_point(?long
,?lat
), #第1引数は検索したデータ bif:st_point(137.85, 34.75), #第2引数は絞り込み範囲の中心 5 #第3引数は絞り込みの広さ )) ?s rdfs:label ?label . }
- 緯度経度検索した値を
提供者別の選択
- データセットの提供者はsourceInfo
- 利用するデータセットが決まっているなら、絞り込む方がクエリは効率的な場合が多い
?s rdfs:label ?label ; schema:temporal time:1860 ;
jps:sourceInfo
/schema:provider
chname:ARC浮世絵ポータル- ARC浮世絵ポータルの中から1860年のアイテムを取り出す
- 所蔵(アクセス提供者)はaccessInfo
- アイテムの所蔵先、関連URLなどは
jps:accessInfo
のリソースにまとめられている SELECT ?access (count(?s) as ?count) WHERE { ?s schema:about keyword:忠臣蔵 ;
jps:accessInfo
/schema:provider
?access } GROUP BY ?access ORDER BY desc(?count)- 忠臣蔵に関するアイテムはどこにどれだけ所蔵されているか
- アイテムの所蔵先、関連URLなどは
画像などの提供者リソース
- サムネイル画像
- アイテムの
schema:image
の値として記述- 正式版では
schema:thumbnail
に変更する可能性あり
- 正式版では
- 提供される場合とされない場合があるので、
OPTIONAL
で取得するとよい ?s schema:creator chname:葛飾北斎 ; rdfs:label ?label . OPTIONAL {?s
schema:image
?thumbnail}
- アイテムの
- 高解像度画像とIIIF
- IIIFマニフェストは文書データなので、アクセス情報の
schema:url
で記述し、sc:Manifest
型を付与している ?s rdfs:label ?label;
jps:accessInfo
/schema:url
?manifest . ?manifest a <http://iiif.io/api/presentation/2#Manifest
>- サムネイルとは別に高解像度画像が提供される場合は、アクセス情報の
schema:associatedMedia
で記述 ?s rdfs:label ?label ; schema:about chname:中村歌右衛門3代目 ;
jps:accessInfo
/schema:associatedMedia
?bigimage
- IIIFマニフェストは文書データなので、アクセス情報の
まとめ
- いくつかの基本方針
- 簡単なクエリからはじめて改造していく
- 正規化値とその同値(
owl:sameAs
)を上手く使う - グラフのつながりを利用する
- テキスト検索はURIでの絞り込みと組み合わせる
- 参考リソース
- SPARQエンドポイントの解説(公式サイト)
- 利活用スキーマ概説(公式サイト)
- Web NDLAのSPARQL API仕様書(SPARQL 1.1の説明。PDF)
- 利活用スキーマの設計と応用(三田図書館情報学会月例会の講演スライド資料)
- 非公式サポートページ(応用例)