NGSI-LDにも挑戦


データ仕様の現状と課題
スマートシティの標準規格(案)
データモデルのユースケース
ツール


Column
Link
用語集

Coppell

Technologies

1. 前提知識



1.1 Linked data
2022-12-13
 Linked Dataとは、データ同士が結び付けられた状態のデータの事です。一番有名なLinked DataはWebページだと思います。Webページを見ると、他のWebページへのリンクが埋め込まれています。Webページをブラウザを通して参照している人は、そのリンクをクリックする事で、他のWebページも参照する事が出来ます。Webページの場合は参照しているのは人間である事が前提ですから、リンクを貼り付けている文字列や前後の文中に、どこへのリンクなのかを記載するのが普通です。また、リンク先は同じWebサイトでも構いませんし、全く違うWebサイトでも構いません。
 Webページ以外でも、同じようにLinked Dataが考えられます。「Fiwareを使って都市OSを動かしてみよう」では、EntityはJSONで表現することを学びましたが、勿論JSONでもLinked Data化する事は可能でした。学んだ事例では、RoomのEntityはFloorのEntityをリンクし、FloorのEntityはBuildingのEntityをリンクしていました。ただ、あの例では単にidを値として埋め込んでいるだけで、その値が他のEntityに対するリンクとは分からず、人間がプログラムをコーディングするときに、リンクであると解釈して使う事が前提となっていました。
 Linked Dataとは何かと聞かれた場合、上記の様に「リンクがあるデータ」とお答えしますが、実はこれはLinked Dataの特徴のマイナーな一面を述べたに過ぎません。外部を参照出来ると言う事は、多くの利点をもたらします。特に大きいのはマシンリーダブルであるという事です。以下、順番に説明します。


1.2 NGSI V2は曖昧だった
2022年8月1日
 「Fiwareを使って都市OSを動かしてみよう」でEntityについて記載しました。例えば、以下の例がありました。


{
   "id": "urn:ngsi-ld:Store:002",
   "type": "Store",
   "name": {
       "type": "Text",
       "value": "セブンイレブン呉市吉浦店"
   },
   "address": {
       "type": "PostalAddress",
       "value": {
           "streetAddress": "吉浦潭鼓町1-1",
           "addressLocality": "呉市",
           "addressRegion": "広島県",
           "postalCode": "7370843"
       }
   },
  "refOffStreetParking": {
       "type": "Relationship",
       "value": "urn:ngsi-ld:OffStreetParking:002"
   },
-- 中略 --
}

この例では、addressとありますが、このアドレスの定義はどこから来たのでしょうか。住所の表記の定義は沢山あります。日本のデジタル庁のコア語彙、同庁GIFのコアデータモデル、同じく行政基本情報データ連携モデル。各々の規定には多少違います。実は、この書き方はschema.orgのaddreddの規定に従ったものでした。でも、どこにもそんなことは書いていませんよね。人間が読むときには特に困りませんが、コンピューターが読むときにはどの規定に従っているのか分からないと解釈に間違いが生じかねません。また、idも処理系の中だけで一意でしたから、他の処理系のEntityを参照する方法は決められていませんでした。


1.3 Contextって何?
2022-12-13
 NGSI V2ではContextとEntityの違いは曖昧でした。「Fiwareを使って都市OSを動かしてみよう」では、データを格納する単位をEntityと呼んでいましたが、WebサイトによってはContext ElementやContextと呼ぶ場合もありました。これに対して、NGSI-LDではContextとEntityは別の概念と捉えています。
 Contextで辞書を引くと、文の前後関係、脈絡、背景、場面などという文字が並びます。また、欧米人の会話表現を「Low Context」、それに対し日本人の様に暗黙の了解を前提とする会話表現を「High Context」と言う事もあります。コンピューターは究極のLow Contextであり、空気を読んだり行間を読んだりすることはありません。従って、コンピューター間でデータ交換を行う際には、Contextを明確に定義しつつ、定義したContextを共有する必要があります。
 尚、EntityはNGSI-LDでもデータを格納する単位であり、変わりません。


1.4 IRI、URI、URL、そしてURN
2022年8月1日
 ここでちょっと用語を整理しておきます。4つの用語が出てきますが、どれも世界で一つの実体を指すものと考えれば大丈夫です。後でこれらの用語が出て来るので、びっくりしない様に一応まとめておきます。
 まず、URLは皆さん良くご存知の通り、Web上のコンテンツを指すアドレスの事です。URLは「Uniform Resource Locator」の略で、つまりインタネット上の場所を指します。URLの凄いところは、世界中で唯一と言う事です。URLが決まればURLが指すコンテンツが一つだけ決まります。つまり、URLはコンテンツのIDとなります。
 URL以外にも世界中で唯一となるIDの文字列があります。これをURNと言います。URNとは 「Uniform Resource Name」の略で、"urn:"から始まる文字列です。そういえば、「Fiwareを使って都市OSを動かしてみよう」で、EntityのIDはこの形式でしたよね。そうです。あんな感じの文字列です。但し、あのIDは世界で唯一であることを保証していませんでしたので正確にURNと言って良いかどうかは議論が残ります。
 で、URIですが、これは「Uniform Resource Identifier」の略で、URLとURNを合わせた上に一般化したものです。標準規約には、以下の例も記載されています。全てURIなのだそうです。

     ftp://ftp.is.co.za/rfc/rfc1808.txt
     http://www.ietf.org/rfc/rfc2396.txt
     ldap://[2001:db8::7]/c=GB?objectClass?one
     mailto:John.Doe@example.com
     news:comp.infosystems.www.servers.unix
     tel:+1-816-555-1212
     telnet://192.0.2.16:80/
     urn:oasis:names:specification:docbook:dtd:xml:4.1.2

 最後はIRIです。実は、URIにはASCIIの文字を使うという制約がありました。日本語など、アルファベットでは表せない文字は使えない事になります。もし使う場合は、「エンコード」という手法でASCII文字列に変換して使っていました。これに対しIRIは「Internationalized Resource Identifier」の略で、文字の制約を大幅に緩和し、Unicodeでも使える様にしたたものです。詳しくは、こちらをご覧ください。


1.5 JSON-LD登場
2022年8月11日
 前記の様な曖昧さを排除するためにIRIを活用する、Linked Dataとあう考え方が生まれました。前記の例をLinked Dataっぽく表記すると、例えば以下の様な感じになります (JSON-LDやNGSI-LDの規則に則った表現ではありません)。

{
   "id": "urn:ngsi-ld:Store:002",
   "type":"https://schema.org/Store",
   "https://schema.org/name": {
       "type": "Text",
       "value": "セブンイレブン呉市吉浦店"
   },
   "http://schema.org/address": {
       "type":"https://schema.org/PostalAddress",
       "value": {
           "https://schema.org/streetAddress": "吉浦潭鼓町1-1",
           "https://schema.org/addressLocality": "呉市",
           "https://schema.org/addressRegion": "広島県",
           "https://schema.org/postalCode": "7370843"
       }
   },
 "refOffStreetParking": {
       "type": "Relationship",
       "value": "urn:ngsi-ld:OffStreetParking:002"
   },
-- 中略 --
}

 この様に、各種Attribute nameやtypeの値をIRI(のURL)にする事で、データの提供者と利用者が同じ定義に基づいてる事が確認出来る様になります。勿論、IRIで参照している先に記述してあるであろう定義が実は曖昧な記述かもしれないというリスクは残りますが、少なくとも同じ定義を参照していると言う事は確認できるわけです。
 具体的に見ていくと、typeの値である"Store"はIRIで示されているので、Storeの定義内容は一意に特定でき、定義が違うのではないかという曖昧さは残りません。addrressの表現も同様ですね。この様に曖昧な表現をIRIで書く事で、曖昧さを排除できています。
 ただ、まだidとかtype等のキーが値として何を求めているのかなど、曖昧さはまだ残っています。refOffStreetParkingという、定義が無いAttributeもどうするか問題です。また、イチイチ"https://schema.org/"を記載するのは煩雑なだけでくな、随分と見難いものになってしまいました。そのでJSON-LDが登場します。


1.5.1 @付きのキーワード
2022年8月1日
 JSON-LDでは、幾つかの@から始まるキーワードを定義しています。これは、予約語に相当するもので、JSON-LDの文では、定義を断らずにいきなり書く事が可能です。以下、代表的なものについて記載します。

キーワード 説明
@type オブジェクトのタイプを指定する事を示します。Entityの第1レベルに出現したときは、Entityのタイプであることを示します。前記の例では、Storeの行が該当します。
Attribnuteに出現したときは、Attributeのタイプである事を示します。前記の例では、nameやaddressに出て来ます
@Context 前項のとおり、表記の短縮に使います。尚、他にも機能はありますので、後でおいおい説明します。
@id IRIであることを示します。Entityの第1レベルにキーとして出現したときは、Entityのidであることを示します。Attributeに出現したときは、IRIだと言う事を示します。
@Value Attributeの値である事を示します

これらのキーワードを使って前記の例を書き直すと、以下の様になります。

{
   "@id": "urn:ngsi-ld:Store:002",
   "@type": "https://schema.org/Store",
   "https://schema.org/name": {
       "@type": "Text",
       "@value": "セブンイレブン呉市吉浦店"
   },
   "http://schema.org/address": {
       "@type": "https://schema.org/PostalAddress",
       "@value": {
           "https://schema.org/streetAddress": "吉浦潭鼓町1-1",
           "https://schema.org/addressLocality": "呉市",
           "https://schema.org/addressRegion": "広島県",
           "https://schema.org/postalCode": "7370843"
       }
   },
 "refOffStreetParking": {
       "@type": "Relationship",
       "@value": "urn:ngsi-ld:OffStreetParking:002"
   },
-- 中略 --
}


1.5.2 @Contextによる表記の短縮
2022年8月1日
 まずは、煩雑で見難くしていた、IRIの改善です。
 JSON-LDでは、文字列にAliasを作ることが出来ます。具体的には、@Contextというキーワードを使います。@Contextは定義と参照の両方が同じキーワードで出て来ます。
 例えば定義は以下となります。

{
   "@Context": {
       "id": "@id",
       "type": "@type",
       "schema": "https://schema.org/",
       "Store": "schema:Store",
       "name": "schema:name",
       "Text": "schema:Text",
       "address": "schema:address",
       "PostalAddress": "schema:PostalAddress",
       "addressLocality": "schema:addressLocality",
       "addressRegion": "schema:addressRegion",
       "postalCode": "schema:postalCode"
   }
}

この記述の意味は、上から順番に"id"や"type"と書いたら"@id"や"@type"と書いていたとして処理してください。"schema"と書いたら"https://schema.org/"と書いたとして処理してくださいと言う意味です。次の"Store"を見ると"schema"と"Store"が記載されています。schemaは"https://schema.org/"の事でしたから、つまり"Store"と書いたら""https://schema.org/Store"と理解してくださいと言う意味になります。以下同様です。
 このファイルを例えばhttp://examplde.com/context.jsonld"に格納しておいたとします。そうすると、大分簡単になりますね。尚、参照する側も同じく、@Contextを使います。

{
   "@Context": "http://example.com/context.jsonld",
   "id": "urn:ngsi-ld:Store:002",
   "type": "Store",
   "name": {
       "type": "Text",
       "value": "セブンイレブン呉市吉浦店"
   },
   "address": {
       "type": "PostalAddress",
       "value": {
           "streetAddress": "吉浦潭鼓町1-1",
           "addressLocality": "呉市",
           "addressRegion": "広島県",
           "postalCode": "7370843"
       }
   },
   "refOffStreetParking": {
       "type": "Relationship",
       "value": "urn:ngsi-ld:OffStreetParking:002"
   },

-- 中略 --
}

大分表記は簡単になりました、というか元に戻りました。たたしまだ、refOffStreetParkingが何者か分かりませんね。


1.5.3 外部参照の定義
2022年8月1日
JSON-LDでは、データのリンクが可能でした。その定義は以下赤字部分の様に記述します。

{
   "@Context": {
       "id": "@id",
       "type": "@type",
       "schema": "https://schema.org/",
       "Store": "schema:Store",
       "name": "schema:name",
       "Text": "schema:Text",
       "address": "schema:address",
       "PostalAddress": "schema:PostalAddress",
       "addressLocality": "schema:addressLocality",
       "addressRegion": "schema:addressRegion",
       "postalCode": "schema:postalCode",
       "refOffStreetParking": {
           "@id": "https://example.com/refOffStreetParking"
           "@type": "@id"
       }
   }
}

 この意味は、refOffStreetParkingというPropertyのidはhttps://example.com/refOffStreetParkingですと言う意味と、この項目の値のタイプは@idつまり、IRIですよと言う事を示しています。これを使うと、Contextの方は以下となります。

{
   "@Context": {
       "http://example.com/context.jsonld",
       "abcd": "http://example.com/json-ld/v1/"
   },
   "id": "urn:ngsi-ld:Store:002",
   "type": "Store",
   "name": {
       "type": "Text",
       "value": "セブンイレブン呉市吉浦店"
   },
   "address": {
       "type": "PostalAddress",
       "value": {
           "streetAddress": "吉浦潭鼓町1-1",
           "addressLocality": "呉市",
           "addressRegion": "広島県",
           "postalCode": "7370843"
       }
   },
   "refOffStreetParking": "abcd:entities/urn:ngsi-ld:OffStreetParking:002",

-- 中略 --
}

 大分見やすくなりましたし、曖昧さも排除できました。
 実は、ここまだの記述は多少ごまかしてv2の書き方で書いていますので、このままでは動きません。正しい表現は、この後の章で詳しく書いていきます。