JSON 請求 API

Solr 支援替代的請求 API,該 API 接受部分或全部由 JSON 物件組成的請求。在某些情況下,此替代 API 可能更佳,因為它具有更高的可讀性和彈性,使其比完全由查詢參數驅動的替代方案更容易使用。還有一些功能只能透過此 JSON 請求 API 存取,例如 JSON 分面 API 的大部分分析功能。

建立 JSON 請求

JSON 請求 API 的核心是其能夠將請求參數指定為請求主體中的 JSON,如下例所示

  • curl

  • SolrJ

curl https://127.0.0.1:8983/solr/techproducts/query -d '
{
  "query" : "memory",
  "filter" : "inStock:true"
}'
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

  • SolrJ

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"
}'
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

  • SolrJ

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.
}'
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

  • SolrJ

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}'
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

  • SolrJ

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
    }
  }
}
'
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 對應項。下表顯示了那些具有對應項的參數

表 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

  • SolrJ

curl "https://127.0.0.1:8983/solr/techproducts/query?fl=name,price"-d '
{
  params: {
    q: "memory",
    rows: 1
  }
}'
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

  • SolrJ

curl "https://127.0.0.1:8983/solr/techproducts/query?FIELD=text&TERM=memory" -d '
{
  query:"${FIELD}:${TERM}",
}'
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 標準的行為。

  • 裸字 (bare words) 可以不用引號括起來

  • 可以使用 //# 插入單行註解

  • 可以使用 /**/ 插入多行 ("C 風格") 註解

  • 字串可以使用單引號括起來

  • 特殊字元可以使用反斜線跳脫

  • 尾隨(多餘)的逗號會被靜默忽略(例如,[9,4,3,]

  • nbsp (不換行空格,\u00a0) 被視為空白字元。

除錯

如果您想查看合併/解析後的 JSON 外觀,您可以開啟除錯模式(debug=timing),它將會與其他除錯資訊一起在 "json" 鍵下返回。請注意,debug=truedebugQuery=true 通常會對效能產生顯著影響,應保留用於除錯。另請注意,debug=query 對於 SolrCloud 中的 JSON facets 沒有影響。