JSON 请求 API
Solr 支持一个备用请求 API,它接受部分或全部由 JSON 对象组成的请求。在某些情况下,此备用 API 可能更可取,因为其可读性和灵活性更高,使其比完全由查询参数驱动的备用 API 更易于使用。还有一些功能只能通过此 JSON 请求 API 访问,例如 JSON 分面 API 的大部分分析功能。
构建 JSON 请求
JSON 请求 API 的核心是其将请求参数指定为请求正文中的 JSON 的能力,如下例所示
curl
curl http://localhost: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 http://localhost: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 'http://localhost: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 http://localhost: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 http://localhost: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 http://localhost: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 等效项。这些参数如下表所示
查询参数 | 同等级别的 JSON 字段 |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
上表中未指定的参数仍可用于 JSON API 请求的主体中,但它们必须放在 params
块中,如下面的示例所示。
curl
curl "http://localhost: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 "http://localhost:8983/solr/techproducts/query?fl=name,price&q=memory&rows=1"
在 其他查询 中描述了 queries
键的用法。
参数替换/宏扩展
当然,通过参数替换进行请求模板化也完全适用于 JSON 请求正文或参数。例如
curl
curl "http://localhost: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);