JSON 请求 API
Solr 支持另一种请求 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);