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 對應項。下表顯示了那些具有對應項的參數
查詢參數 | JSON 欄位對應項 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
上表中未指定的參數仍然可以在 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);