JSON リクエスト API

Solr は、リクエストの一部または全体が JSON オブジェクトで構成される代替リクエスト API をサポートしています。この代替 API は、可読性と柔軟性が向上しているため、すべてクエリパラメータ駆動型の代替手段よりも使いやすい場合があります。また、JSON ファセット API の多くの分析機能など、この JSON リクエスト API を介してのみアクセスできる機能もあります。

JSON リクエストの作成

JSON リクエスト API の核心は、以下の例に示すように、リクエストボディに JSON としてリクエストパラメータを指定できることです。

curl

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query" : "memory",
  "filter" : "inStock:true"
}'

SolrJ

final JsonQueryRequest simpleQuery =
    new JsonQueryRequest().setQuery("memory").withFilter("inStock:true");
QueryResponse queryResponse = simpleQuery.process(solrClient, COLLECTION_NAME);

JSON オブジェクトは通常、リクエストボディで送信されますが、`json` 接頭辞付きクエリパラメータの値として送信することもできます。これは、リクエストボディで指定された値をオーバーライドまたは補足するために使用できます。たとえば、クエリパラメータ `json.limit=5` は、JSON リクエストボディで提供される `limit` 値をオーバーライドします。以下の例に示すように、JSON ボディ全体を単一の `json` クエリパラメータで指定することもできます。

curl https://127.0.0.1:8983/solr/techproducts/query -d 'json={"query":"memory"}'

JSON パラメータのマージ

単一のリクエストで複数の `json` パラメータが提供された場合、Solr はリクエストを処理する前にパラメータ値をマージしようとします。

JSON リクエスト API には、複数の値を受け入れるプロパティ (`filter`、`fields` など) がいくつかあります。マージプロセス中に、これらの「複数値」プロパティのすべての値が保持されます。ただし、多くのプロパティ (`query`、`limit` など) は単一の値しか持つことができません。複数のパラメータ値が互いに競合する場合、次の優先順位ルールに基づいて単一の値が選択されます。

  • 従来のクエリパラメータ (`q`、`rows` など) が最優先され、他の指定された値よりも優先されます。

  • `json` 接頭辞付きクエリパラメータが次に考慮されます。

  • JSON リクエストボディで指定された値は優先順位が最も低く、他の場所に指定されていない場合にのみ使用されます。

この階層化されたマージにより、両方の長所を生かすことができます。リクエストは、読みやすく構造化された JSON を使用して指定できます。ただし、ユーザーは、頻繁に変更されるリクエストの部分を分離する柔軟性も備えています。これは、以下の例で実際に確認できます。この例では、`json.` スタイルのパラメータを組み合わせて、メインの JSON ボディにある値をオーバーライドおよび補足しています。

curl

curl 'https://127.0.0.1:8983/solr/techproducts/query?json.limit=5&json.filter="cat:electronics"' -d '
{
  query: "memory",
  limit: 10,
  filter: "inStock:true"
}'

SolrJ

final ModifiableSolrParams overrideParams = new ModifiableSolrParams();
final JsonQueryRequest queryWithParamOverrides =
    new JsonQueryRequest(overrideParams)
        .setQuery("memory")
        .setLimit(10)
        .withFilter("inStock:true");
overrideParams.set("json.limit", 5);
overrideParams.add("json.filter", "\"cat:electronics\"");
QueryResponse queryResponse = queryWithParamOverrides.process(solrClient, COLLECTION_NAME);

これは以下と同等です。

curl

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "memory",
  "limit": 5,     // this single-valued parameter was overwritten.
  "filter": ["inStock:true","cat:electronics"]    // this multi-valued parameter was appended to.
}'

SolrJ

final JsonQueryRequest query =
    new JsonQueryRequest()
        .setQuery("memory")
        .setLimit(5)
        .withFilter("inStock:true")
        .withFilter("cat:electronics");
QueryResponse queryResponse = query.process(solrClient, COLLECTION_NAME);

同様に、スマートマージを使用して、以下の例のように、適切なリクエストボディがまったくない JSON API リクエストを作成することもできます。

curl

curl https://127.0.0.1:8983/solr/techproducts/query -d 'q=*:*&rows=1&
  json.facet.avg_price="avg(price)"&
  json.facet.top_cats={type:terms,field:"cat",limit:3}'

SolrJ

final ModifiableSolrParams params = new ModifiableSolrParams();
final SolrQuery query = new SolrQuery("*:*");
query.setRows(1);
query.setParam("json.facet.avg_price", "\"avg(price)\"");
query.setParam("json.facet.top_cats", "{type:terms,field:\"cat\",limit:3}");
QueryResponse queryResponse = solrClient.query(COLLECTION_NAME, query);

これは次のリクエストと同等です。

curl

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query": "*:*",
  "limit": 1,
  "facet": {
    "avg_price": "avg(price)",
    "top_cats": {
      "type": "terms",
      "field": "cat",
      "limit": 5
    }
  }
}
'

SolrJ

final JsonQueryRequest jsonQueryRequest =
    new JsonQueryRequest()
        .setQuery("*:*")
        .setLimit(1)
        .withStatFacet("avg_price", "avg(price)")
        .withFacet("top_cats", new TermsFacetMap("cat").setLimit(3));
QueryResponse queryResponse = jsonQueryRequest.process(solrClient, COLLECTION_NAME);

ファセットと分析コマンドの詳細については、JSON ファセット API を参照してください。

サポートされているプロパティと構文

現在、Solrの従来のクエリパラメータの一部のみが、第一級のJSON equivalent を持っています。対応するパラメータは以下の表に示されています。

表1. 標準クエリパラメータとJSONフィールドの対応表
クエリパラメータ JSONフィールド

q

query

fq

filter

start

offset

rows

limit

fl

fields

sort

sort

json.facet

facet

json.<param_name>

<param_name>

json.queries.<query_name>

queries

上記の表に指定されていないパラメータは、JSON APIリクエストの本体で使用できますが、以下の例に示すように、params ブロック内に配置する必要があります。

curl

curl "https://127.0.0.1:8983/solr/techproducts/query?fl=name,price"-d '
{
  params: {
    q: "memory",
    rows: 1
  }
}'

SolrJ

final ModifiableSolrParams params = new ModifiableSolrParams();
params.set("fl", "name", "price");
final JsonQueryRequest simpleQuery =
    new JsonQueryRequest(params).withParam("q", "memory").withParam("rows", 1);
QueryResponse queryResponse = simpleQuery.process(solrClient, COLLECTION_NAME);

params ブロックに配置されたパラメータは、リクエストのクエリパラメータにそのまま追加されたかのように動作します。上記のリクエストは、以下と同等です。

curl "https://127.0.0.1:8983/solr/techproducts/query?fl=name,price&q=memory&rows=1"

queries キーの使い方は、追加クエリで説明されています。

パラメータ置換 / マクロ展開

もちろん、パラメータ置換によるリクエストテンプレートは、JSONリクエスト本体またはパラメータでも完全に機能します。例えば

curl

curl "https://127.0.0.1:8983/solr/techproducts/query?FIELD=text&TERM=memory" -d '
{
  query:"${FIELD}:${TERM}",
}'

SolrJ

final ModifiableSolrParams params = new ModifiableSolrParams();
params.set("FIELD", "text");
params.set("TERM", "memory");
final JsonQueryRequest simpleQuery = new JsonQueryRequest(params).setQuery("${FIELD}:${TERM}");
QueryResponse queryResponse = simpleQuery.process(solrClient, COLLECTION_NAME);

JSON拡張機能

Solrは、リクエストAPIで **Noggit** JSONパーサーを使用します。 Noggitは、より緩やかなJSON解析が可能であり、JSON標準からのいくつかの逸脱を許容します。

  • ベアワードは引用符で囲まなくても構いません。

  • 単一行コメントは、// または # を使用して挿入できます。

  • 複数行(「Cスタイル」)コメントは、/**/ を使用して挿入できます。

  • 文字列は単一引用符で囲むことができます。

  • 特殊文字はバックスラッシュでエスケープできます。

  • 末尾の(余分な)カンマは無視されます(例:[9,4,3,])。

  • nbsp(改行なしスペース、\u00a0)は空白として扱われます。

デバッグ

マージ/解析されたJSONがどのように見えるかを確認したい場合は、デバッグ(debug=timing)を有効にすると、他のデバッグ情報とともに「json」キーの下に表示されます。 debug=true および debugQuery=true は、パフォーマンスに大きな影響を与える可能性があるため、デバッグ用に予約する必要があります。 また、debug=query は、SolrCloudのJSONファセットには影響しません。