🔥

Snorql for Japan Searchのカスタマイズ方法の調査

2022/11/29に公開

概要

ジャパンサーチで使用されている「Snorql for Japan Search」のカスタマイズ方法について、その調査結果です。随時更新予定です。また誤りも含まれている可能性が高いので、ご注意ください。

メニュー

ページのタイトルを変更する

snorql_def.js
_poweredByLabel: "Cultural Japan", // "Japan Search",

問い合わせ先のエンドポイントを変更する

snorql_def.js
_endpoint: "https://ld.cultural.jp/sparql/", //"https://jpsearch.go.jp/rdf/sparql/",

poweredByLinkのURLを変更する

snorql_def.js
_poweredByLink: "https://cultural.jp/", // "https://jpsearch.go.jp/",

その他のフッター部分を編集する

index.html
<footer>
      <a href="./">Snorql</a> for <a id="poweredby" href="#">Japan Search</a>.
      Use
      <a href="https://ld.cultural.jp/sparql">basic SPARQL endpoint</a>
      <!-- <a href="https://jpsearch.go.jp/rdf/sparql">basic SPARQL endpoint</a> --> for
      your application.
      <!--
      <a href="https://jpsearch.go.jp/api/sparql-explain/"
        >SPARQLエンドポイント解説</a
      >
      -->
    </footer>

バージョンを変更する

snorql_def.js
var _sldb_version = "v0.0.1"; //"v2.20.1";

トップページの説明

snorql_ldb.js
intro_tmpl = hdef.intro_tmpl || [
	"%s0%は、Snorql for Japan Searchを理解するためのチュートリアルです。"
	//"%s0%は、SPARQLクエリ構築支援と分かりやすい結果表示のために、%s1%を<a href=\"https://www.kanzaki.com/works/ld/jpsearch/snorql_ldb-about\">拡張したツール</a>です。アプリケーションからのSPARQLクエリには%s2%を利用してください。", 
	//"%s0% is an <a href=\"https://www.kanzaki.com/works/ld/jpsearch/snorql_ldb-about\">extension</a> of %s1% to make SPARQL query building easier and show results much understandable. Use %s2% for application query."
],

introの説明

snorql_def.js
intro: [
			["テスト", "Test"]
			//["入力欄下もしくは右にクエリ例があります。<a href=\"https://jpsearch.go.jp/api/sparql-explain/\">ジャパンサーチSPARQLエンドポイント解説</a>も参照してください。", "Query examples are provided below (or right-hand side of) the text area. See also <a href=\"https://www.kanzaki.com/works/ld/jpsearch/primer/\">Japan Search RDF Model Primer</a> for the general description."],
			//["エンドポイントの利用方法は<a href=\"https://jpsearch.go.jp/api/sparql-explain/\">SPARQLエンドポイント解説</a>をご覧ください。", "See <a href=\"https://www.kanzaki.com/works/ld/jpsearch/primer/\">Japan Search RDF Model Primer</a> for the general description of this endpoint."],
			//["用いているRDFモデルの概要は<a href=\"https://jpsearch.go.jp/api/introduction/\">利活用スキーマ概説</a>をご覧ください。", "See <a href=\"https://jpsearch.go.jp/api/introduction/\">Introduction to Japan Search SPARQL Endpoint</a> (in Japanese) for the RDF model."],
			//["Snorql for Japan Searchの概要は<a href=\"https://www.kanzaki.com/works/ld/jpsearch/snorql_ldb-about\">Snorql for Japan Seachを使う</a>をご覧ください。", "<a href=\"https://www.kanzaki.com/works/ld/jpsearch/snorql_ldb-about\">About Snorql for Japan Search</a> has basic explanation of this Snorql extension."]
		],

名前空間を追加する

namespaces.js
var D2R_namespacePrefixes = {
    "jps": "https://jpsearch.go.jp/term/property#",
    // ...
    owl: 'http://www.w3.org/2002/07/owl#',
    "dcndl": "http://ndl.go.jp/dcndl/terms/",
};

初期クエリを変更する

snorql_def.js
//default query to be set on text area when loaded without user query ユーザクエリ無しでロードされた時にtextareaに表示
		//default_query: "SELECT DISTINCT * WHERE {\n\t?s schema:creator chname:葛飾北斎 ;\n\trdfs:label ?label .\n\tOPTIONAL {?s schema:image ?image}\n}\nLIMIT 100",
		default_query: `select distinct * where {
			?s ?v ?o . 
		}`,

クエリ例を変更する

"ns": ["edm"]のように指定することで、検索クエリにprefixを追加することができる。ただし、同ファイルのexample_nsにprefixの情報を追記する必要あり。

snorql_examples.js
Snorqldef.example = [
	{
		"mlabel": [
			"「中村」をタイトルに含むアイテム", 
			"Example 1"
		],
		"query": 
`SELECT * WHERE {
	?cho rdfs:label ?label .
	?label bif:contains "'中村'"
}
`,
		"ns": ["edm"]
	},
	/*
	{
		"mlabel": ["クラス(型)別コンテンツ数。シンプルな集約の例です。jps:sourceInfoを加えることでアイテムに限定しています。", "Count items by type. A simple example of aggregation. jps:sourceInfo ensures the resulting ?cho are items (not agents, locations, etc)"],
		"query" : 
`SELECT ?type (count(?cho) as ?count) WHERE {
	?cho a ?type ;
		jps:sourceInfo ?source .
} GROUP BY ?type
`,
		"ns" : [ ]	//list of ns prefixes defined in example_ns, if necessary 必要に応じてexample_nsで定義した接頭辞リスト
	},`,

リクエストされたURIに加えてサブリソースを同時にdescribeする設定の変更

デフォルトでは、フラグメント識別子accessinfosourceinfoが追加されるが、ここではaccessinfoのみを追加するように設定した例。

snorql_def.js
data_frags: ["accessinfo"], //["accessinfo", "sourceinfo"],

この設定が追加されるURIのパターンは以下で指定されている。ここでは、デフォルトで追加されているhttps://ld.cultural.jpを削除した例。

snorql_def.js
//snorqlおよび_ldbのis_home_uriを範囲するためのエンドポイント基本データURIパターン。trueならラベルや他情報を追加取得する
		datauri_pat: "^(https://jpsearch.go.jp|http://purl.org/net/ld/jpsearch)/data/", 
		//"^(https://jpsearch.go.jp|https://ld.cultural.jp|http://purl.org/net/ld/jpsearch)/data/",	//basic 'record' namespace pattern

この設定により、以下のように、フラグメント識別子が追加されなくなる。

datauri_patを修正することで、基本データURIパターンを変更することができる。例えば以下のように設定することで、xxx.yyy.zzzがURIに含まれるリソースについて、ラベルや他情報が追加取得されます。

snorql_def.js
datauri_pat: "xxx.yyy.zzz", 

サムネイル画像の表示

サムネイル画像に使用するプロパティは以下で指定されている。schema:image以外を使用したい場合には、ここを変更する。

snorql_def.js
thumb_prop: "schema:image",	//maybe we should use schema:thumbnail

domを操作している箇所は以下。

snorql_ldb.js
/**
 * generates an image element and insert as the first child
 * @param {DOMNode} div	element node that has the description table
 * @param {Object} option	an object to pass extra parameters e.g. width, recover url
 * @param {String} url	target image source url
 * @param {String} recover_url	alternative image url to be used when the target url failed
 * @return {DOMNode}	<img> element
 */
prim_image_url: function(div, option, url, recover_url){
...
}

describeの結果表示で、同プロパティの値が多数ある時のデフォルト最大表示数(折りたたみ)

snorql_def.js
//describeの結果表示で、同プロパティの値が多数ある時のデフォルト最大表示数(折りたたみ)
showrows: 10, //6,

値URIを直接のリンクとして設定するプロパティ

画像のURLなどは、リンクをクリックすると、当該リンクに直接アクセスする。

これは以下で設定されている。

snorql_def.js
//properties that set direct link rather than describe link
//値URIを直接のリンクとして設定するプロパティ(通常はdescribe=URIリンクを設定する)
dlink_props: [
	"schema:url",
	"schema:relatedLink",
	//"schema:image",
	"schema:associatedMedia",
	"schema:thumbnail",
	"schema:sameAs",
	"schema:usageInfo",	//2022-08-15
	"jps:sourceData",
	"rdfs:seeAlso"
],

ライセンスURIバッジ

snorql_ldb.js
case this.ns.schema + "license":
			this.addex.if_indiv_policy(ovtd, myoval);
			break;
snorql_ldb.js
/// from more_on_property
	/**
	 * add a license badge, also test license uri is an individual (non conditional) policy, and add "ipd" class if true
	 * ライセンスURIバッヂを加え、さらに「単一ポリシー定義」であるかどうかを確認し、該当したら"ipd"クラスを設定する。
	 * @param {DOMNode} ovtd	<td> element that contains license uri node, to add a badge and "ipd" class
	 * @param {String} licenseuri	the license uri in question
	 */
	if_indiv_policy: function(ovtd, licenseuri){
		var that = this, binds,
		query = "PREFIX pds: <http://purl.org/net/ns/policy#>\n" +
		"PREFIX dct: <http://purl.org/dc/terms/>"+
		"select distinct ?ref ?ipd where {<" + licenseuri + "> dct:isVersionOf? ?ref .\n" +	//added distinct to avoid dup badges2021-01-22
		"?ref a pds:ReferencePolicy .\n" +
		"OPTIONAL{<" + licenseuri + "> a ?ipd . ?ipd rdfs:subClassOf pds:IndividualPolicyDefinition}}";
		this.qh.handler(null, query, function(res){
			if(!(binds = that.qh.check_res(res, "ipd results", licenseuri + " (license uri)"))) return false;
			binds.forEach(function(bind){
				if(bind.ipd) ovtd.classList.add("ipd");	//individual policy definition
				if(bind.ref) test_icon(bind.ref.value, ovtd);
			});
			return true;
		});
		function test_icon(reflicense, ovtd){
			var src = that.license_badge(reflicense, "s");
			if(src){
				var imgelt = Util.dom.element("img");
				imgelt.src = src;
				ovtd.appendChild(imgelt);
			}
		}
	},

_namespace設定以外に表示時にQNameとする接頭辞:名前空間URIマッピング

デフォルトではhttp://purl.org/net/ns/policy#はQNameとなっていないが、以下を設定することで、QNameとする接頭辞を追加できる。

snorql_def.js
//prefixes to display properties as QName (in addtion to basic snorql._namespace) used by SPARQLResultFormatter._formatURI
		//_namespace設定以外に表示時にQNameとする接頭辞:名前空間URIマッピング
		more_ns: {
			"ind": "https://jpsearch.go.jp/entity/ind/",
			...
			"policy": "http://purl.org/net/ns/policy#"
		}

EasySPARQLのクエリ内容

例えば、「どこ」は以下で設定されている。

EasySPARQL.js
/**
	 * 場所をキーにしたクエリ生成
	 * @param {String} val	変数値
	 * @return {String}	WHERE句のトリプルパターン。緯度経度も加える
	 */
	where: function(val){
		var matched,
		query = "?s ",
		geopat = "schema:geo [schema:latitude ?lat; schema:longitude ?long ] ";
		if((matched = val.match(/^(.{2,3}?)[都府県]?$/))	//{2,3}のみだと"京都府"は"府"も含めてマッチする
			&& (this.prefectures.indexOf(matched[1]) !== -1)
		){
			//JPSのplace:は都道府県なし(place:三重 など)
			query += this.prop.spatial + " ?place . ?place " + this.prop.value + " place:" + matched[1] + " .\n" +
			"\tOPTIONAL {?place " + geopat + "}";
			
		}
		...

describeアイテムでのプロパティ表示順の設定

snorql_def.js
//preferred order of properties for described item. used in JsonRDFFormatter.
		//describeアイテムでのプロパティ表示順の設定
		proporder: {
			//the latter the heigher priority (top)
			//優先順位の「低い」順に指定するプロパティ定義配列
			showup: [
				"jps:within",
				"schema:longitude",
				// "schema:latitude",
				"schema:geo",
				...

EasySPARQLを非表示にする

index.html
<div>
      <form action="" method="get" id="moreform" class="ja">
      <!--
       <label><span lang="en">Who</span><span lang="ja">だれ</span>:<input type="text" name="who"/></label>
       <label><span lang="en">Where</span><span lang="ja">どこ</span>:<input type="text" name="where"/></label>
       <label><span lang="en">When</span><span lang="ja">いつ</span>:<input type="text" name="when"/></label>
       <label><span lang="en">Title</span><span lang="ja">タイトル</span>:<input type="text" name="title"/></label>
       <label><span lang="en">Text</span><span lang="ja">テキスト</span>:<input type="text" name="text"/></label>
       <input type="submit" value="EasySPARQL"/>
	-->
      </form>
	<link rel="stylesheet" href="codemirror/lib/codemirror.css">
	...
</div>

Discussion