カスタムJSONの変換とインデックス作成

Solrの構造に変換することなくインデックスを作成したいJSONドキュメントがある場合、更新リクエストにいくつかのパラメータを含めることでSolrに追加できます。

これらのパラメータは、単一のJSONファイルを複数のSolrドキュメントに分割する方法と、フィールドをSolrのスキーマにマッピングする方法に関する情報を提供します。1つ以上の有効なJSONドキュメントは、設定パラメータを使用して/update/json/docsパスに送信できます。

マッピングパラメータ

これらのパラメータを使用すると、複数のSolrドキュメントに対してJSONファイルを読み取る方法を定義できます。

split

オプション

デフォルト:なし

入力JSONを複数のSolrドキュメントに分割するパスを定義し、単一のJSONファイルに複数のドキュメントがある場合は必須です。JSON全体が単一のSolrドキュメントになる場合は、パスを「/」にする必要があります。

パイプ(|)で区切ることで、複数のsplitパスを渡すことができます(例:split=/|/foo|/foo/bar)。あるパスが別のパスの子である場合、それらは自動的に子ドキュメントになります。

f

必須

デフォルト:なし

ドキュメントのフィールド名をSolrのフィールド名にマッピングする多値マッピングを提供します。パラメータの形式はtarget-field-name:json-pathで、f=first:/firstのようになります。json-pathは必須です。target-field-nameはSolrドキュメントのフィールド名で、オプションです。指定しない場合は、入力JSONから自動的に導出されます。デフォルトのターゲットフィールド名は、フィールドの完全修飾名です。

ここではワイルドカードを使用できます。詳細については、下記のフィールド名にワイルドカードを使用するを参照してください。

mapUniqueKeyOnly

オプション

デフォルト:false

このパラメータは、入力JSONのフィールドがスキーマに存在せず、スキーマレスモードが有効になっていない場合に特に便利です。これにより、すべてのフィールドがデフォルトの検索フィールド(dfパラメータを使用)にインデックスされ、uniqueKeyフィールドのみがスキーマ内の対応するフィールドにマッピングされます。入力JSONにuniqueKeyフィールドの値がない場合は、UUIDが生成されます。

df

オプション

デフォルト:なし

mapUniqueKeyOnlyフラグが有効になっている場合、更新ハンドラはデータをインデックスする必要があるフィールドを必要とします。これは、他のハンドラがデフォルトの検索フィールドとして使用するのと同じフィールドです。

srcField

オプション

デフォルト:なし

JSONソースが格納されるフィールドの名前です。これは、split=/の場合(つまり、JSON入力ファイルを単一のSolrドキュメントとしてインデックス化する場合)にのみ使用できます。アトミック更新では、フィールドとドキュメントの同期がずれることに注意してください。

echo

オプション

デフォルト:false

デバッグ目的でのみ使用します。ドキュメントをレスポンスとして返す場合は、trueに設定します。何もインデックスされません。

たとえば、2つのドキュメントを含むJSONファイルがある場合、次のような更新リクエストを定義できます。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json/docs'\
'?split=/exams'\
'&f=first:/first'\
'&f=last:/last'\
'&f=grade:/grade'\
'&f=subject:/exams/subject'\
'&f=test:/exams/test'\
'&f=marks:/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

このリクエストでは、「exams」に複数のドキュメントが含まれていると定義しています。さらに、入力ドキュメントのいくつかのフィールドをSolrフィールドにマッピングしています。

更新リクエストが完了すると、次の2つのドキュメントがインデックスに追加されます。

{
  "first":"John",
  "last":"Doe",
  "marks":90,
  "test":"term1",
  "subject":"Maths",
  "grade":8
}
{
  "first":"John",
  "last":"Doe",
  "marks":86,
  "test":"term1",
  "subject":"Biology",
  "grade":8
}

前の例では、Solrで使用したいすべてのフィールドは、入力JSONと同じ名前でした。その場合、この例のようにfパラメータのjson-path部分のみを指定することで、リクエストを簡素化できます。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/first'\
'&f=/last'\
'&f=/grade'\
'&f=/exams/subject'\
'&f=/exams/test'\
'&f=/exams/marks'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

この例では、フィールドパス(例:/exams/test)に単純に名前を付けました。Solrは、JSON入力からのフィールドの内容を、同じ名前のフィールドに自動的にインデックスに追加しようとします。

インデックス作成時に、フィールドが事前にスキーマに存在しない場合、ドキュメントは拒否されます。したがって、スキーマレスモードを使用していない場合は、すべてのフィールドを事前に作成する必要があります。スキーマレスモードで作業している場合、存在しないフィールドは、Solrがフィールドタイプを最適に推測して、動的に作成されます。

複数リクエストでのパラメータの再利用

SolrのリクエストパラメータAPIを使用して、パラメータを保存して再利用できます。

examsフィールドでドキュメントを分割し、他のいくつかのフィールドをマッピングするパラメータを定義したいとしましょう。次のようなAPIリクエストを行うことができます。

V1 API

 curl https://127.0.0.1:8983/solr/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

V2 API ユーザー管理/単一ノードSolr

curl https://127.0.0.1:8983/api/cores/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

V2 API SolrCloud

curl https://127.0.0.1:8983/api/collections/techproducts/config/params -H 'Content-type:application/json' -d '{
 "set": {
   "my_params": {
     "split": "/exams",
     "f": ["first:/first","last:/last","grade:/grade","subject:/exams/subject","test:/exams/test"]
 }}}'

ドキュメントを送信する際には、定義したパラメータセットの名前を指定してuseParamsパラメータを使用します。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json?useParams=my_params' -H 'Content-type:application/json' -d '{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [{
      "subject": "Maths",
      "test": "term1",
      "marks": 90
    },
    {
      "subject": "Biology",
      "test": "term1",
      "marks": 86
    }
  ]
}'

ワイルドカードによるフィールド名の指定

すべてのフィールド名を明示的に指定する代わりに、ワイルドカードを指定してフィールドを自動的にマッピングすることができます。

ワイルドカードはjson-pathの末尾でのみ使用でき、分割パスにワイルドカードを使用することはできません。これが2つの制限です。

アスタリスク1つ*は直接の子要素のみにマップされ、アスタリスク2つ**はすべての子孫に再帰的にマップされます。ワイルドカードパスマッピングの例を以下に示します。

  • f=$FQN:/**:すべてのフィールドをJSONフィールドの完全修飾名($FQN)にマップします。完全修飾名は、階層内のすべてのキーをピリオド(.)で区切って連結することで取得されます。fパスマッピングが指定されていない場合、これがデフォルトの動作です。

  • f=/docs/*:docs配下のすべてのフィールドを、JSONで指定された名前でマップします。

  • f=/docs/**:docs配下とその子要素のすべてのフィールドを、JSONで指定された名前でマップします。

  • f=searchField:/docs/*:/docs配下のすべてのフィールドを「searchField」という単一のフィールドにマップします。

  • f=searchField:/docs/**:/docs配下とその子要素のすべてのフィールドをsearchFieldにマップします。

ワイルドカードを使用すると、前の例をさらに簡素化できます。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json'\
'?split=/exams'\
'&f=/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

JSON入力で見つかったフィールド名でフィールドをインデックス付けしたいので、f=/**のダブルワイルドカードは、すべてのフィールドとその子孫をSolrの同じフィールドにマップします。

すべての値を単一のフィールドに送信し、そのフィールドで全文検索を実行することも可能です。これは、フィールドやスキーマを意識せずにJSONドキュメントを盲目的にインデックス付けしてクエリを実行するのに適したオプションです。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json'\
'?split=/'\
'&f=txt:/**'\
 -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

上記の例では、すべてのフィールドを'txt'という名前のSolrのフィールドに追加するように指定しました。これにより、複数のフィールドが単一のフィールドに追加されるため、選択するフィールドは複数値である必要があります。

デフォルトの動作では、ノードの完全修飾名(FQN)が使用されます。したがって、次のようにフィールドマッピングを定義しない場合

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json?split=/exams'\
    -H 'Content-type:application/json' -d '
{
  "first": "John",
  "last": "Doe",
  "grade": 8,
  "exams": [
    {
      "subject": "Maths",
      "test"   : "term1",
      "marks"  : 90},
    {
      "subject": "Biology",
      "test"   : "term1",
      "marks"  : 86}
  ]
}'

インデックス付けされたドキュメントは、次のようなフィールドを持つインデックスに追加されます。

{
  "first":"John",
  "last":"Doe",
  "grade":8,
  "exams.subject":"Maths",
  "exams.test":"term1",
  "exams.marks":90},
{
  "first":"John",
  "last":"Doe",
  "grade":8,
  "exams.subject":"Biology",
  "exams.test":"term1",
  "exams.marks":86}

単一ペイロード内の複数ドキュメント

この機能は、1行に1つのドキュメントを指定するJSON Lines形式(.jsonl)のドキュメントをサポートしています。

例:

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '
{ "first":"Steve", "last":"Jobs", "grade":1, "subject":"Social Science", "test":"term1", "marks":90}
{ "first":"Steve", "last":"Woz", "grade":1, "subject":"Political Science", "test":"term1", "marks":86}'

または、この例のように、ドキュメントの配列でも可能です。

V1 API

curl 'https://127.0.0.1:8983/solr/techproducts/update/json/docs' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

V2 API ユーザー管理/単一ノードSolr

curl 'https://127.0.0.1:8983/api/cores/techproducts/update/json' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

V2 API SolrCloud

curl 'https://127.0.0.1:8983/api/collections/techproducts/update/json' -H 'Content-type:application/json' -d '[
{"first":"Steve", "last":"Jobs", "grade":1, "subject":"Computer Science", "test":"term1", "marks":90},
{"first":"Steve", "last":"Woz", "grade":1, "subject":"Calculus", "test":"term1", "marks":86}]'

カスタムJSONインデックス作成のヒント

  1. スキーマレスモード:これはフィールドの作成を自動的に処理します。フィールドの推測は必ずしも期待通りではないかもしれませんが、機能します。最適な方法は、スキーマレスモードでローカルサーバーを設定し、いくつかのサンプルドキュメントをインデックス作成して、実際の環境で適切なフィールドタイプを使用してそれらのフィールドを作成してからインデックス作成することです。

  2. 事前に作成されたスキーマ:echo=trueを指定して、ドキュメントを/update/json/docsエンドポイントに投稿します。これにより、作成する必要があるフィールド名のリストが表示されます。実際にインデックスを作成する前に、フィールドを作成してください。

  3. スキーマなし、全文検索のみ:JSONで全文検索を実行するだけで済みます。「JSONデフォルトの設定」セクションで説明されているように設定してください。

JSONデフォルトの設定

任意のJSONを/update/json/docsエンドポイントに送信することができ、コンポーネントのデフォルト設定は次のとおりです。

<initParams path="/update/json/docs">
  <lst name="defaults">
    <!-- this ensures that the entire JSON doc will be stored verbatim into one field -->
    <str name="srcField">_src_</str>
    <!-- This means the uniqueKeyField will be extracted from the fields and
         all fields go into the 'df' field. In this config df is already configured to be 'text'
     -->
    <str name="mapUniqueKeyOnly">true</str>
    <!-- The default search field where all the values are indexed to -->
    <str name="df">text</str>
  </lst>
</initParams>

したがって、パラメータが渡されない場合、JSONファイル全体が_src_フィールドにインデックスされ、入力JSONのすべての値がtextという名前のフィールドに格納されます。uniqueKeyの値がある場合は保存され、入力JSONから値を取得できない場合は、UUIDが作成され、uniqueKeyフィールド値として使用されます。

あるいは、「複数リクエストでのパラメータの再利用」セクションで前述したように、リクエストパラメータ機能を使用してこれらのパラメータを設定します。

V1 API

 curl https://127.0.0.1:8983/solr/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

V2 API ユーザー管理/単一ノードSolr

 curl https://127.0.0.1:8983/api/cores/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

V2 API SolrCloud

 curl https://127.0.0.1:8983/api/collections/techproducts/config/params -H 'Content-type:application/json' -d '{
"set": {
  "full_txt": {
    "srcField": "_src_",
    "mapUniqueKeyOnly" : true,
    "df": "text"
}}}'

これらのパラメータを使用するには、各リクエストにuseParams=full_txtパラメータを送信します。