JSONドキュメント・コンテンツのテキスト索引の作成

この項では、前述の例を使用して、NoSQL表に格納されているJSONドキュメントのコンテンツにテキスト索引を作成し、Elasticsearchの結果の索引に対して様々な全文検索問合せを実行する方法について説明します。

特定の表のフィールドに格納される各値の型が表スキーマから推測されるOracle NoSQL Databaseセカンダリ索引とは異なり、テキスト索引では、索引付けされる各属性の型はスキーマから推測できないため、CREATE FULLTEXT INDEXコマンドで指定する必要があります。表のスキーマによって、表の特定のフィールド(列)の値がJSONドキュメントであることがOracle NoSQLに通知されますが、各要素がJSON書式のコンテンツである場合を除いて、ドキュメント自体の内部構造についてはOracle NoSQLに通知されません。Oracle NoSQLは、索引付けされるJSONドキュメント内の属性、およびそれらの属性の索引付けの際に使用されるデータ型を認識しないため、CREATE FULLTEXT INDEXコマンドを使用してその情報をOracle NoSQLに明示的に指定する必要があります。

したがって、JSONドキュメントを含む列にテキスト索引を作成するには、索引付けする属性を指定することに加えて、JSONパス表記でマッピング仕様を常に指定する必要もあります。これにより、索引付けするドキュメント内の属性が、そのような各属性に索引付けするときに使用するようElasticsearchに通知するデータ型とともに、Oracle NoSQLに通知されます。

たとえば、前の項では、セカンダリ索引が作成されて問合せが行われ、献金の合計が100万から2000万ドルである現在の民主党上院議員をすべて検索しました。ただし、司法委員会または歳出委員会(あるいはその両方)の委員でもある、献金の合計が100万から2000万ドルである現在の民主党上院議員をすべて検索するように、この検索を絞り込むとします。このような検索では、テキスト索引をセカンダリ索引のかわりに作成する必要があります。これは、委員会情報が文字列のネストした配列に含まれているという理由だけでなく、全文検索を実行できるようにするためでもあります。

これを行うには、最初に管理CLIから次のコマンドを実行して、目的のテキスト索引を作成します。

kv-> execute 'CREATE FULLTEXT INDEX jsonTxtIndex ON 
    jsonTable (
      jsonField.current{"type":"boolean"},
      jsonField.party{"type":"string","analyzer":"standard"},
      jsonField.duties.committe{"type":"string"},
      jsonField.contrib{"type":"double"})';

前の項の例のようにjsonTableという表のts列でセカンダリ索引を作成するのではなく、前述のコマンドでは、かわりにその列に格納されているドキュメントの特定の属性で構成されるテキスト索引を作成します。前述の例の索引では、献金の合計が100万から2000万ドルである現在の民主党上院議員をすべて検索できましたが、先ほど作成されたテキスト索引では、検索を絞り込むことができます。テキスト索引を使用すると、司法委員会または歳出委員会(あるいはその両方)の委員でもある、献金の合計が100万から2000万ドルである現在の民主党上院議員をすべて検索できます。

前述のコマンドを使用してテキスト索引を作成したら、Oracle NoSQLストアが登録されているElasticsearchクラスタへのネットワーク・アクセスを備えたノードからcurlコマンドを実行し、目的の検索基準を満たすドキュメントについてElasticsearchに問い合せることができます。たとえば、esHostという名前のノードから、次を実行します。

curl –X GET 
'http://esHost:9200/ondb.kvstore.jsontable.jsontxtindex/_search?pretty' 
'-d {query":{"bool":{
"must":{"match":{"jsonField.party":"Democrat"}},
"must":{"match":"jsonField.current":"true"}},
"must":{"range":{"jsonField.contrib":{
        "gte":"1000000.00","lte":20000000.00"}}},
"must":"match":{"jsonField.duties.committe":
                  "Judiciary Apropriations"}}}}}'

前述のように、前述の問合せのondb.kvstore.jsontable.jsontxtindexは、Oracle NoSQLによってElasticsearchに作成される索引の名前です。ここで、kvstoreはOracle NoSQLストアの名前、jsontableは、索引付けされるJSONドキュメントを含むそのストアの表(jsonTable)に対応し、jsontxtindexはストアで保持されるテキスト索引メタデータに対応しています。

前述のElasticsearch問合せによって生成される出力は、次のようになります(読みやすさを考慮して、多少再フォーマットされています)。

{
  ....
  "hits" : {
    "total" : 31,
    "max_score" : 1.4695805,

    "hits" : [ {
      "_index" : "ondb.kvstore.jsontable.jsontindex",
      "_type" : "text_index_mapping",
      "_id" : "/w/0001",
      "_score" : 1.4695805,

      "_source":{"_pkey":{"_table":"jsontable","id":"1"},  
        "jsonField":"{"description":
                          "Senior Senator for Ohio"},
        "jsonField"{"current":"true"},
        "jsonField":{"congress_numbers":[223,224,225]},
        "jsonField":{"party":"Democrat"},
        "jsonField":{"seniority":37},
        "jsonFeld":{"personal":{"birthday":1952-11-09"}},
        "jsonField":{"personal":{"lastname":"Brown"}},
        "jsonField":{"contrib":257134.93},
        "jsonField":{"duties":{"committee":["Ways and 
            Means","Judiciary","Democratic Steering"]}}, 
        "jsonField":{"duties":{"caucus":["Congressional 
            Automotive","Human Rights","Steel Industry"]}},
        "jsonField":{"personal":{"address":{"home":{
                                   "state":"OH"}}}},
        "jsonField":{":"personal":{"address":{"home":{
                                   "city":"Columbus"}}}}}
    } ],
    ....
  }
}

前の項で説明したセカンダリ索引に対する問合せとは異なり、この問合せはOracle NoSQLストアではなくElasticsearchクラスタに対して実行されることを理解しておくことが重要です。また、ここで作成するテキスト索引では、ネストした配列jsonField.duties.committeeの値に対して全文検索を実行できます。セカンダリ索引では実行できないものもあります。