CyberLibrarian

【注意】 このドキュメントは、IIIFのIIIF Content Search API 1.0の和訳です。
このドキュメントの正式版はIIIFのサイト上にある英語版であり、このドキュメントには翻訳に起因する誤りがありえます。誤訳、誤植などのご指摘は、訳者までお願い致します。

First Update: 2016年6月10日


IIIFコンテンツ検索API 1.0

このドキュメントのステータス

本バージョン: 1.0.0

最新安定版: 1.0.0

編集者

Copyright © 2012-2016 Editors and contributors. Published by the IIIF Consortium under the CC-BY license, see disclaimer.


目次

1. はじめに

IIIF(「トリプル・アイ・エフ」と発音)プレゼンテーションAPIでは、アノテーションにより、分散しているシステムからコンテンツが集められます。そのコンテンツには、画像(IIIF画像APIサービスでアクセスすることが多い)、音声、動画、リッチ・テキストやプレーンテキストなどが含まれるかもしれません。活力あるダイナミックなシステムでは、そのコンテンツは、多数の情報源から得ることができ、リッチで 多様で、大量でありえます。多数のコンテンツの種類のうち、テキスト資源は、テキスト化データ(transcription)、知的コンテンツの翻訳または編纂、コメント、解説、タグ付け、またはその他のオブジェクトに関するアノテーションとして検索を行うのに適しています。

この仕様では、IIIFのコンテキスト内でこれらの検索を実行するための相互運用性のメカニズムについて説明します。この仕様の範囲は、マニフェスト(Manifest)、範囲(Range)、コレクション(Collection)などの、1つのIIIF資源内のアノテーション・コンテンツの検索です。相互作用が既存のIIIFパターンとの整合性をできる限り保つよう、最善の努力を尽くします。メタデータやその他の記述的なプロパティーの検索は、この作業の範囲です。

未知のコンテンツの検索をより容易に行えるように、検索語のオートコンプリート関連のサービスについても規定しています。オートコンプリート・サービスとは、具体的には、検索された用語を検索のクエリにシンプルにコピーできることを保証する検索サービスを指します。

フィードバックはiiif-discuss@googlegroups.comにお送りください。

1.1. ユースケース

プレゼンテーションAPI内のアノテーションを検索できるユースケースには次のものが含まれます。

  • 本、新聞、その他の主要なテキストのコンテンツ内の単語またはフレーズを見つけるために、OCRにより作成されたテキストを検索する。
  • 学術的な成果のクラウド・ソーシングや変換により提供されるテキスト化されたコンテンツを検索する。
  • オブジェクトの適切な部分にジャンプするために、コンテンツの未加工のテキスト化データではなく、翻訳や編纂などの多様なコンテンツを検索する。
  • 定義済みの章や記事などのテキストの一部を検索する。
  • 資源または議論の発見メカニズムとして、資源に関してユーザが提供するコメントを検索する。
  • コンテンツまたはオブジェクトを比較するために、テキストの類似部分を発見する。

検索応答を用いて構築できるユーザ・インターフェースには、マッチした単語のハイライト表示、オブジェクト内のマッチした場所のヒートマップ(heatmap)の提供、オブジェクト内のポイント間をジャンプするメカニズムの提供が含まれます。オートコンプリート・サービスは、ユーザが選択範囲に存在する用語を識別するために役立ちます。

1.2. 用語

このドキュメントの「しなければならない(must)」、「してはならない(must not)」、「必須である/要求される(required)」、「することになる(shall)」、「することはない(shall not)」、「すべきである/する必要がある(should)」、「すべきでない/する必要がない(should not)」、「推奨される(recommended)」、「することができる/してもよい(may)」、「選択できる/任意である(optional)」というキーワードは、RFC 2119で記述されているように解釈されるべきです。

2. 概要

IIIFプレゼンテーションAPIは、画像やその他のコンテンツを豊かで理解可能な方法でユーザに示すのに最低限必要な情報をビューアに提供します。これらのコンテンツ資源にはテキストアノテーションを関連付けることができます。アノテーションは、マニフェスト自身、シーケンス、範囲、レイヤーなどの、プレゼンテーションAPIの構造要素と関連付けることもできます。さらに、アノテーションは、それに対してアノテーションを付与することで返答を行い、コメント、テキスト化、編纂、翻訳に関する議論をスレッド化することができます。

アノテーションは、一般的に、アノテーション・リストの形で表示用アプリケーションに提供され、リスト内のすべてのアノテーションが同じ資源またはその部分をターゲットとしています。これらのリストは、その存在が分かっている場合は、クライアントがリンクをシンプルに辿って検索できるように、マニフェスト・ドキュメントから直接参照できます。固定され、精選されたコンテンツの場合、アノテーションが頻繁に変更されることはなく、複数のサーバーに分散されている可能性も低いため、これは発見に適した方法です。アノテーション・リストは、これらをアノテーションの情報源などでグルーピングするためにレイヤーに記述でき、それにより、ユーザがそのグループをまとめて操作できるようになります。

しかし、アノテーションは常に変化している可能性があるため、これは、コメント形式のアノテーション、クラウド・ソースまたは分散しているテキスト化データ、自動化されたOCRテキスト化データの修正などにはあまり有用ではありません。さらに、オブジェクトのすべてのビューを経由せずに個々のアノテーションを迅速に発見できることは、合理的なユーザ体験にとって不可欠です。この仕様は、IIIFの仕様群にこの性能を追加します。

ユーザは、単語やフレーズを検索する性能のほかに、どのような用語を検索すべきかの提案があれば便利だと思うでしょう。この機能は、しばしばオートコンプリートや先行入力と呼ばれ、1つのオブジェクトのコンテキストにおいて言語とコンテンツの手掛かりとなります。オートコンプリート・サービスは、用語をクエリの一部として入力できる検索サービスと関連しています。

検索サービスはクエリを用いますが、それには一般的に検索語やURIが含まれており、アノテーションの作成日や最終更新日、アノテーションの動機、アノテーションを作成したユーザなどの他のプロパティーにより、さらなるフィルタリングが行われる可能性があります。

3.1. サービス記述

あらゆるプレゼンテーションAPI源は検索サービスと関連付けることができます。資源は、検索されるコンテンツの範囲を決定します。マニフェストと関連付けられているサービスは、キャンバス上のすべてのアノテーションまたはマニフェスト以下の他のオブジェクトを検索し、特定の範囲と関連付けられているサービスは、その範囲内のキャンバスのみを検索し、キャンバスのサービスは、その特定のキャンバスのアノテーションのみを検索するでしょう。

サービスの記述はサービスへのリンク仕様で規定されているパターンに従います。記述ブロックには、「http://iiif.io/api/search/1/context.json」という値を持つ@contextプロパティー、「http://iiif.io/api/search/1/search」という値を持つprofileプロパティー、および、検索を実行できるURIが含まれている@idプロパティーがなければならなりません(must)。

サービス記述ブロックの例は下記のとおりです。

{
  // ... the resource that the search service is associated with ...
  "service": {
    "@context": "http://iiif.io/api/search/1/context.json",
    "@id": "http://example.org/services/identifier/search",
    "profile": "http://iiif.io/api/search/1/search"
  }
}

3.2. リクエスト

検索リクエストは、特定のプレゼンテーションAPI資源と関係するサービスに対して行われます。様々な資源に関連付けられているサービスのURIは、クライアントが求める検索範囲に対して正しいURIを用いることができるよう、違うものでなければなりません。検索を実行するためには、検索語を指定するクエリ・パラメータにより、HTTP GET(POSTではなく)を用いてサービスにリクエストを行わなければなりません(must)。

3.2.1. クエリ・パラメータ

推奨されている(recommended)qを除き、リクエストではその他のすべてのパラメータはオプションです(optional)。パラメータが空または提供されていない場合は、デフォルトは、そのパラメータによって検索とマッチするアノテーションを限定しないということです。値が提供されているけれどもアノテーションにフィールドがない場合は、検索はそのアノテーションとマッチしません。例えば、アノテーションに作成者がなく、クエリでuserパラメータが指定されている場合、アノテーションはクエリとマッチしません。

サーバーは、qmotivationのパラメータを実装すべきで(should)、その他のパラメータを実装することができます(may)。リクエストで受け取られるけれども実装されていないパラメータは、無視されなければならず(must)、下記で説明している、応答内のレイヤーのignoredプロパティーに含まれているべきです(should)。

パラメータ 定義
q 空白で区切られた検索語のリスト。検索語は、単語(テキスト本文内を検索するため)またはURIでありえます(アノテーション本文資源のIDを検索するため)(may)。複数の空白で区切られた用語のセマンティクスは、サーバーの実装に依存します。
motivation 空白で区切られた動機の用語のリスト。複数の動機が付与されている場合は、いずれかの動機が存在していれば、アノテーションは検索とマッチします。予期される値を下記で示しています。
date 空白で区切られた日付の範囲のリスト。作成された日付が、付与されている日付のいずれかの範囲内に収まっていれば、アノテーションはマッチします。日付は、YYYY-MM-DDThh:mm:ssZ/YYYY-MM-DDThh:mm:ssZというISO8601形式で提供しなければなりません(must)。日付はUTCで表現しなければならず(must)、Zベースの形式で提供しなければなりません(must)。
user 空白で区切られたユーザのIDであるURIのリスト。複数のユーザが付与されている場合は、いずれかのユーザがそのアノテーションを作成したのであれば、アノテーションは検索とマッチします。

動機パラメータの共通の値は下記のとおりです。

動機 定義
painting sc:paintingという動機を持つアノテーションのみ
non-painting sc:painting以外の動機を持つアノテーション
commenting oa:commentingという動機を持つアノテーション
describing oa:describingという動機を持つアノテーション
tagging oa:taggingという動機を持つアノテーション
linking oa:linkingという動機を持つアノテーション

その他の動機も可能で、オープン・アノテーション仕様のリストのすべてから「oa:」接頭辞を除いたものを利用できるはずです(should)。その他、コミュニティ固有の動機は、接頭辞を含めるか、その完全なURIを用いるべきです(should)。

3.2.2. リクエストの例

このリクエストの例:

http://example.org/services/manifest/search?q=bird&motivation=painting

これは、テキストのコンテンツ内に「bird」という単語があるアノテーションを検索し、paintingという動機を持つでしょう。これは、サービスが関連付けられている資源内のアノテーションを検索するでしょう。

3.3. プレゼンテーションAPI互換応答

サーバーからの応答はアノテーション・リストであり、プレゼンテーションAPIに少しの機能を追加したフォーマットに従っています。これにより、すでにAnnotationList形式を実装しているクライアントは、検索結果をサポートするためにさらに実装作業を行わずに済みます。

検索結果は正規IIIF構文形式のアノテーションとして返されます。すべてのアノテーションが1つのキャンバスをターゲットとしているプレゼンテーションAPIのものであるというデフォルト状況ではなく、アノテーションが複数のキャンバスのものでありえることに注意してください。

3.3.1. シンプルなリスト

最もシンプルな応答は、規則的なアノテーション・リストとそっくりで、マッチングしたすべてのアノテーションが1つの応答で返されます。@idの値はクエリで用いられているURIと同じですが、サーバーは、無視するクエリ・パラメータがignoredプロパティーで示されていれば、それを除くことができます(may)。

クライアントがマッチしたアノテーションの総数を知りたい場合は、すべてのマッチが返されるときに、resourcesプロパティーのアノテーションの数を数えることができます。URIでアノテーションを別途逆参照可能であったとしても、完全なアノテーションの記述が応答に含まれていなければなりません(must)。

{
  "@context":"http://iiif.io/api/presentation/2/context.json",
  "@id":"http://example.org/service/manifest/search?q=bird&motivation=painting",
  "@type":"sc:AnnotationList",

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-line",
      "@type": "oa:Annotation",      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "A bird in the hand is worth two in the bush"
      },
      "on": "http://example.org/identifier/canvas1#xywh=100,100,250,20"
    }
    // Further matching annotations here ...
  ]
}

3.3.2. 結果のページ付け

アノテーションのリストが長い場合は、サーバーは、しばしばページと呼ばれる複数のセクションに応答を分割することを選択できます。個々のページはアノテーション・リストであり、クライアントが集合全体をトラバースできるように、他のページを参照できます。これは、プレゼンテーションAPIのバージョン2.1で導入されたページ付け機能を用いますが、バージョン2.0と下位互換性があります。現在の応答に続く、結果の次のページは、アノテーション・リストのnextプロパティーで参照されなければならず(must)、前のページは prevプロパティーで参照されるべきです(should)。

@idプロパティーで示されている最初のアノテーション・リストのURIは、検索をリクエストするためにクライアントが用いるものと違うものでありえます(may)。個々のページには、全結果集合の中の最初の結果の位置を示す、整数の値を持つstartIndexプロパティーもあるべきで(should)、最初のアノテーションのインデックスは0です。例えば、クライアントが、最初のページに10件のヒットが含まれているようにリクエストした場合、そのstartIndexは0になり、2番目のページのstartIndexは10で、それは11件目のヒットになります。

すべてのページは、マッチしたアノテーションの全検索集合を表すレイヤー内に含まれています。レイヤーは、個々のページ・アノテーション・リストのwithinプロパティーの値であり、プロパティーを持ったオブジェクトとして記録されます。

レイヤーには、「sc:Layer」という値を持つ@typeプロパティーがなければなりません(must)。それは、最初と最後のアノテーションリストページのURIを、それぞれfirstlastのプロパティーで参照すべきです(should)。レイヤーには、クエリにより生成されるヒットの総数であるtotalプロパティーがあるべきで(should)、それは、@idプロパティーの値として付与されたURIを持つことができます(may)。

リクエストの例:

http://example.org/service/manifest/search?q=bird

そして、合計が125件のマッチのアノテーションの最初のページに対する応答は次のとおりです。

{
  "@context":"http://iiif.io/api/presentation/2/context.json",
  "@id":"http://example.org/service/manifest/search?q=bird&page=1",
  "@type":"sc:AnnotationList",

  "within": {
    "@type": "sc:Layer",
    "total": 125,
    "first": "http://example.org/service/manifest/search?q=bird&page=1",
    "last": "http://example.org/service/identifier/search?q=bird&page=13"
  },
  "next": "http://example.org/service/identifier/search?q=bird&page=2",
  "startIndex": 0,

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-line",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "A bird in the hand is worth two in the bush"
      },
      "on": "http://example.org/identifier/canvas1#xywh=100,100,250,20"
    }
    // Further annotations from the first page here ...
  ]
}

3.3.3. ターゲット資源構造

アノテーションには、ターゲット(onプロパティーの資源)が内在する構造への参照を含むことができます。含んでいる資源のURIとタイプを示さなければならず(must)、labelを含んでいるべきです(should)。

この構造は、プレゼンテーションAPIのプロパティーのみを用いているものの、共通のパターンではなく、それゆえ、クライアントがそれを予期しないかもしれないため、明示的に呼び出されます。

{
  "@context":"http://iiif.io/api/search/1/context.json",
  "@id":"http://example.org/service/manifest/search?q=bird&motivation=painting",
  "@type":"sc:AnnotationList",

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-line",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "A bird in the hand is worth two in the bush"
      },
      "on": {
        "@id": "http://example.org/identifier/canvas1#xywh=100,100,250,20",
        "within": {
          "@id": "http://example.org/identifier/manifest",
          "type": "sc:Manifest",
          "label": "Example Manifest"
        }
      }
    }
    // Further annotations here ...
  ]
}

3.4 検索API固有応答

一般的なアノテーションの機能ではなく、クライアントに返すと役立つ、検索結果固有のプロパティーがありえます。そのようなプロパティーの例には、マッチしたコンテンツの前後のテキスト(結果のスニペットが表示できるように)、マッチしたテキスト自身(大文字小文字の正規化、語幹処理、ワイルドカードが適用された時に)、一緒に検索クエリを満たすアノテーションへの参照(フレーズが複数のアノテーションにまたがる時)が含まれます。

これらの応答には検索(訳注:「Search」であるため検索APIを指すと思われる。)の具体的な情報が含まれているため、@contextの値は、プレゼンテーションAPIと検索APIコンテキストURIがその順序で含まれている配列でなければなりません(must)。これによって、2つのAPIを、できる限り同期性を保ちながら別々に開発できるようになります。

既存のソリューションの上に徐々に構築してゆき、これらの機能をサポートしていないクライアントにグレイスフル・デグラデーションを提供し、プレゼンテーションAPIとの互換性を保持するため、検索API固有の情報は、レイヤーのignoredプロパティーではなく、hitsと呼ばれるアノテーション・リスト内の2番目のリストに含まれています。アノテーション・リストはこのプロパティーを持つことができ(may)、サーバーはこの機能をサポートできます(may)。

サポートされている場合は、hitsリストの個々のエントリーはsearch:Hitオブジェクトです。このタイプは@typeプロパティーの値として含まれていなければなりません。ヒット・オブジェクトは、ヒットのannotationsプロパティーの値としてのリストにおいて、追加情報を提供する1つ以上のアノテーションを参照します。参照はアノテーションの@idプロパティーの値に対して作成され、したがって、アノテーションには、この追加情報を可能とするためのURIがなければなりません(must)。

基本的な構造は下記のとおりです。

{
  "@context":[
      "http://iiif.io/api/presentation/2/context.json",
      "http://iiif.io/api/search/1/context.json"
  ],
  "@id":"http://example.org/service/manifest/search?q=bird&page=1",
  "@type":"sc:AnnotationList",

  "within": {
    "@type": "sc:Layer"
    // Result set information here ...
  },

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno1",
      "@type": "oa:Annotation"
      // More regular annotation information here ...
    }
    // Further annotations from the first page here ...
  ],

  "hits": [
    {
      "@type": "search:Hit",
      "annotations": [
        "http://example.org/identifier/annotation/anno1"
      ]
      // More search specific information for anno1 here ...
    }
    // Further hits for the first page here ...
  ]
}

3.4.1. 無視されたパラメータ

サーバーがリクエストのいずれかのパラメータを無視した場合、レイヤーが存在していなければならず(must)、値が無視されたパラメータのリストであるignoredプロパティーを持っていなければなりません(must)。

前例のリクエストが下記のとおりであり、

http://example.org/service/manifest/search?q=bird&user=http%3A%2F%2Fexample.com%2Fusers%2Fazaroth42

リクエストを処理する時にユーザ・パラメータが無視された場合、応答は次のとおりになるでしょう。

{
  "@context":[
      "http://iiif.io/api/presentation/2/context.json",
      "http://iiif.io/api/search/1/context.json"
  ],
  "@id":"http://example.org/service/manifest/search?q=bird&page=1",
  "@type":"sc:AnnotationList",

  "within": {
    "@type": "sc:Layer",
    "total": 125,
    "ignored": ["user"]
  },
  "next": "http://example.org/service/identifier/search?q=bird&page=2",
  "startIndex": 0,

  "resources": [
    // Annotations ...
  ]
}

3.4.2. 検索語のスニペット

最もシンプルなヒット・オブジェクトへの追加は、マッチングしたアノテーションのテキストの前後にテキストを追加表示することです。これにより、クライアントは、マッチングしたテキスト自身ではなく、マッチングしたテキストを周辺コンテンツとの関係で表すスニペットを構築できます。これは、OCR(Optical Character Recognition)によってテキストの位置が生成された時に利用できるような、サービスにおいてキャンバス上のテキストが単語レベルで区切られている場合に最も有用です。

サービスは、beforeプロパティーをヒットに追加してアノテーションのコンテンツの前に若干のテキスト(charsで提供される)を表示することができ(may)、afterプロパティーを追加してアノテーションのコンテンツの後に若干のテキストを表示することもできます(may)。

例えば、このドキュメントの例文の「bird」というクエリ用語の検索において、サーバーが完全な単語レベルの座標を持っている場合は、次のとおりになります。

http://example.org/service/manifest/search?q=bird

サーバーは複数形の「birds」にマッチします。

{
  "@context":[
      "http://iiif.io/api/presentation/2/context.json",
      "http://iiif.io/api/search/1/context.json"
  ],
  "@id":"http://example.org/service/manifest/search?q=bird",
  "@type":"sc:AnnotationList",

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-bird",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "birds"
      },
      "on": "http://example.org/identifier/canvas1#xywh=200,100,40,20"
    }
    // Further annotations here ...
  ],

  "hits": [
    {      "@type": "search:Hit",
      "annotations": [
        "http://example.org/identifier/annotation/anno-bird"
      ],
      "before": "There are two ",
      "after": " in the bush"
    }
    // Further hits for the first page here ...
  ]
}

3.4.3. 検索語のハイライト

多くのシステムは完全な単語レベルの座標情報を持っておらず、行または段落レベルでの区切りに限定されています。この場合には、クライアントが取ることができる最善策は、アノテーション全体を表示し、その中のヒットした部分をハイライトすることです。これは、以前のユースケースとは似て非なるものです。この場合は、単語はアノテーションのcharsプロパティー内のどこかに出現し、クライアントは、それを目立たせる必要があります。以前の状況では、単語はアノテーションのコンテンツ全体であり、その情報はリストで表示するのに便利なものでした。

このケースでは、クライアントは、サービスがヒットを作成する要因となったテキストがどれであり、それを確実にハイライトし、マッチしなかったテキストをハイライトしないようにするために、コンテンツのどこにそれが存在しているかの情報を十分に持っている必要があります。これを行うために、サービスは、オープン・アノテーションTextQuoteSelectorオブジェクトにより、アノテーションのコンテンツ内のマッチした用語の前後にテキストを補うことができます。TextQuoteSelectorsには、探すべきテキストを正確に記録するためにexact、マッチの前のテキストにはprefix、マッチの後のテキストにはsuffixという3つのプロパティーがあります。

これは下記のようなものでありえます。

{
  "@type": "oa:TextQuoteSelector",
  "exact": "birds",
  "prefix": "There are two ",
  "suffix": " in the bush"
}

複数の単語が同じアノテーション内のクエリにマッチするかもしれないため、selectorsプロパティー内のオブジェクトとしてヒットに複数のセレクターが与えられる可能性があります。例えば、「b」で始まるすべての単語を検索するために、検索にワイルドカードを用いれば、同じアノテーションに2回マッチするでしょう。

http://example.org/service/manifest/search?q=b*

結果は下記のようになるでしょう。

{
  "@context":[
      "http://iiif.io/api/presentation/2/context.json",
      "http://iiif.io/api/search/1/context.json"
  ],
  "@id":"http://example.org/service/manifest/search?q=b*&page=1",
  "@type":"sc:AnnotationList",

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-line",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "There are two birds in the bush."
      },
      "on": "http://example.org/identifier/canvas1#xywh=200,100,40,20"
    }
    // Further annotations here ...
  ],

  "hits": [
    {
      "@type": "search:Hit",
      "annotations": [
        "http://example.org/identifier/annotation/anno-line"
      ],
      "selectors": [
        {
          "@type": "oa:TextQuoteSelector",
          "exact": "birds",
          "prefix": "There are two ",
          "suffix": " in the bush"
        },
        {
          "@type": "oa:TextQuoteSelector",
          "exact": "bush",
          "prefix": "two birds in the ",
          "suffix": "."
        }        
      ]
    }
    // Further hits for the first page here ...
  ]
}

3.4.4. 複数アノテーションのヒット

テキストの一部(単語、行、段落、ページ、任意の部分など)と、そのテキストをクライアントに提示するアノテーションとの調整に柔軟性があることから考えると、1つの複数用語検索に複数のアノテーションがマッチする場合がありえます。これらの違いは、主にテキストとアノテーションが生成される方法によるもので、手作業で作成されたテキストとOCRで生成されたテキストとでは、非常に異なるものになるでしょう。

例えば、このように手作業でテキスト化されているため、アノテーションは行ごとに分割されており、2行のテキストがあると想定します。この例では、最初の行は「A bird in the hand」で、2行目は「is worth two in the bush」であり、検索は「hand is」というフレーズに対するものです。したがって、マッチは両方の行のアノテーションにまたがります。代わりに、アノテーションが単語レベルであれば、あらゆるフレーズ検索に複数のアノテーションが必要となるでしょう。

このようなケースでは、1つのヒットを作り出すために2つ以上のアノテーションが必要であるため、ヒットよりもアノテーションの方が多くなります。ヒットのmatchプロパティーにより、アノテーションにまたがるテキストを捉えることがきます。

{
  "@context":[
      "http://iiif.io/api/presentation/2/context.json",
      "http://iiif.io/api/search/1/context.json"
  ],
  "@id":"http://example.org/service/manifest/search?q=hand+is",
  "@type":"sc:AnnotationList",

  "resources": [
    {
      "@id": "http://example.org/identifier/annotation/anno-bird",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "A bird in the hand"
      },
      "on": "http://example.org/identifier/canvas1#xywh=200,100,150,30"
    },
    {
      "@id": "http://example.org/identifier/annotation/anno-are",
      "@type": "oa:Annotation",
      "motivation": "sc:painting",
      "resource": {
        "@type": "cnt:ContentAsText",
        "chars": "is worth two in the bush"
      },
      "on": "http://example.org/identifier/canvas1#xywh=200,140,170,30"
    }
    // Further annotations here ...
  ],

  "hits": [
    {
      "@type": "search:Hit",
      "annotations": [
        "http://example.org/identifier/annotation/anno-bush",
        "http://example.org/identifier/annotation/anno-are"
      ],
      "match": "hand is",
      "before": "A bird in the ",
      "after": " worth two in the bush"
    }
    // Further hits for the first page here ...
  ]
}

4. オートコンプリート

オートコンプリート・サービスは、用語の最初の文字が提供された時に、関連する検索サービスのqパラメータに追加できる用語を返します。

4.1. サービス記述

オートコンプリート・サービスは、用語補完を提供する対象である検索サービス内に組み込まれます。これにより、個々に独自のオートコンプリート・サービスを持つ複数の検索サービスが可能となります。

オートコンプリート・サービスには、相互作用可能なサービスのURIの値を持つ@idプロパティーがなければならず(must)、それを他のタイプのサービスと区別するために「http://iiif.io/api/search/1/autocomplete」という値のprofileプロパティーがなければなりません。

{
  // Resource that the services are associated with ...
  "service": {
    "@context": "http://iiif.io/api/search/1/context.json",
    "@id": "http://example.org/services/identifier/search",
    "profile": "http://iiif.io/api/search/1/search",
    "service": {
      "@id": "http://example.org/services/identifier/autocomplete",
      "profile": "http://iiif.io/api/search/1/autocomplete"
    }
  }
}

4.2. リクエスト

リクエストは、検索リクエストと非常に似ていますが、オブジェクト内の用語の発生回数を制約することができる付加的なパラメータが1つあります。オートコンプリート・サービスにおいて必須である(required)qパラメータの値は、サービスにより補完される用語の先頭文字列です。例えば、「bir」というクエリ用語は、「bird」、「biro」、「birth」、「birthday」に補完されます。

用語は、それに空白が含まれているかどうかを問わず、完全な文字列として構文解析すべきです。例えば、「green bir」という検索語では、「green」とマッチし、かつ、「bir」で始まる語も含まれている領域に対してオートコンプリートが行われるべきではなく、「green bir」という文字列で始まる用語を検索すべきです。

その他のパラメータ(motivationdateuser)がサポートされている場合は、応答の用語の集合を、それらのフィルタとマッチしたアノテーションの用語のみに絞り込みます。例えば、動機が「painting」であると示されていれば、描かれているものをテキスト化したテキストのみが応答の用語のリストに提供されるでしょう。

4.2.1. クエリのパラメータ

パラメータ 定義
min インデックス内の用語の最小発生回数で、応答内に出現させるためのもの。これが存在していない場合、デフォルトは1です。このパラメータのサポートはオプションです(optional)。

4.2.2. リクエストの例

リクエストの例

http://example.org/service/identifier/autocomplete?q=bir&motivation=painting&user=http%3A%2F%2Fexample.com%2Fusers%2Fazaroth42

4.3. 応答

応答は、用語、その用語に対する検索へのリンク、検索により得られるマッチの数などの、シンプルなオブジェクトのリスト(「search:TermList」)です。リスト内で提供される用語の数は、サーバーによって決定されます。

サービスによって処理されなかったパラメータは、主たる「TermList」オブジェクトのignoredプロパティーにおいて返されなければなりません(must)。値は文字列の配列でなければなりません(must)。

用語のリスト内のオブジェクトはすべて@typeが「search:Term」であり、これは、明示的に含むことができますが(may)、その必要はありません。用語オブジェクトには下記の多くのプロパティーがあります。

  • マッチした用語はmatchプロパティーの値として付与され、存在していなければなりません(must)。
  • 実行する検索へのリンクはurlプロパティーの値であり、これは存在していなければなりません(must)。
  • 用語に対するマッチの数はcountプロパティーの整数値であり、存在しているべきです(should)。
  • マッチの代わりに表示するためのラベルは、labelプロパティーの値として付与され、存在することができますmay。国際化が可能となるように、複数のラベルを付与できます。

用語は、アルファベット順にソートした昇順で提供されるべきですが(should)、最も頻度の高いマッチが最初に来るように、用語の総数の降順で提供するなど、その他の順序も認められています。

上記のリクエストの例により、下記の応答が生成されるかもしれません。

{
  "@context": "http://iiif.io/api/search/1/context.json",
  "@id": "http://example.org/service/identifier/autocomplete?q=bir&motivation=painting",
  "@type": "search:TermList",
  "ignored": ["user"],
  "terms": [
    {
      "match": "bird",
      "url": "http://example.org/service/identifier/search?motivation=painting&q=bird",
      "count": 15
    },
    {
      "match": "biro",
      "url": "http://example.org/service/identifier/search?motivation=painting&q=biro",
      "count": 3
    },
    {
      "match": "birth",
      "url": "http://example.org/service/identifier/search?motivation=painting&q=birth",
      "count": 9
    },
    {
      "match": "birthday",
      "url": "http://example.org/service/identifier/search?motivation=painting&q=birthday",
      "count": 21
    }
  ]
}

マッチした文字列をそのまま用いるのではなく、ユーザに表示するための1つ以上のlabelをURIに連携づけたり、qパラメータで検索できる他のデータに連携づけたりすることもできます。これは、語幹処理やその他の用語の正規化が行われた場合に、処理後の用語ではなく元の用語を表示するためにも有用でありえます。

{
  "@context": "http://iiif.io/api/search/1/context.json",
  "@id": "http://example.org/service/identifier/autocomplete?q=http%3A%2F%2Fsemtag.example.org%2Ftag%2Fb&motivation=tagging",
  "ignored": ["user"],
  "terms": [
    {
      "match": "http://semtag.example.org/tag/bird",
      "url": "http://example.org/service/identifier/autocomplete?motivation=tagging&q=http%3A%2F%2Fsemtag.example.org%2Ftag%2Fbird",
      "count": 15,
      "label": "bird"
    },
    {
      "match": "http://semtag.example.org/tag/biro",
      "url": "http://example.org/service/identifier/autocomplete?motivation=tagging&q=http%3A%2F%2Fsemtag.example.org%2Ftag%2Fbiro",
      "count": 3,
      "label": "biro"
    }
  ]
}

5. プロパティーの定義

after
検索により特定のアノテーションとのマッチングをもたらしたテキストの後に表示されるテキストの断片。値は1つの文字列でなければなりません(must)。
  • ヒットはafterプロパティーを持つことができます(may)。
before
検索により特定のアノテーションとのマッチングをもたらしたテキストの前に表示されるテキストの断片。値は1つの文字列でなければなりません(must)。
  • ヒットはbeforeプロパティーを持つことができます(may)。
count
用語の出現回数。値は正の整数でなければなりません(must)。
  • 用語はcountプロパティーを持っているべきです(should)。
ignored
サーバーが受け取ったものの、クエリの処理には取り入れられなかったパラメータのセット。値は文字列の配列でなければなりません(must)。
  • TermListまたはLayerは、ignoredプロパティーを持つことができ(may)、サーバーがクエリ・パラメータを無視する場合は、それを持っていなければなりません(must)。
match
検索により特定のアノテーションとのマッチングをもたらしたテキスト。値は1つの文字列でなければなりません(must)。
  • ヒットはmatchプロパティーを持つことができます(may)。
  • 用語はmatchプロパティーを持っていなければなりません(must)。

付録

A. リクエスト・パラメータ要件

パラメータ リクエストで必要 検索で必要 オートコンプリートで必要
q 推奨 推奨 必須
motivation オプション 推奨 オプション
date オプション オプション オプション
uri オプション オプション オプション
min オプション n/a オプション

B. バージョン付け

この仕様はセマンティック・バージョニングに従っています。実施方法の詳細については、APIのバージョン付けのノートを参照してください。

C. 謝辞

このドキュメントの作成に、アンドリューWメロン財団の助成による寛大な支援をいただきました。

継続的な関与、革新的なアイデア、およびフィードバックに関し、IIIFのメンバーに感謝申し上げます。

D. 変更履歴

日付 説明
2016-05-12 バージョン1.0 (Lost Summer)
2015-07-20 バージョン0.9 (Trip Life)