For AI agents: this page is also available as Markdown at /docs/compat-solr.md. Every docs page is: add .md to its URL. llms.txt lists them all.
Solr compatibility
WarpSearch serves the Solr HTTP API for each collection at https://api.warpsearch.io/compat/solr/{collection}. The collection name replaces the Solr core or collection name in your existing URLs. Requests use Solr parameters, and responses come back in Solr's JSON shapes.
As with the other compatibility endpoints, a request is translated exactly where possible. If only scores would differ, it runs and a Warning: 299 header and responseHeader.warnings say what was approximated. Anything else fails with 400 in Solr's error shape, with a metadata entry naming unsupported_feature. Parameters that only tune performance or routing (cache, cost, facet.method, distrib, shards.*, indent) are accepted silently. Other parameters WarpSearch does not read are reported as warnings.
#Connect
Create an API key in the management console. Send it as Authorization: Bearer ws_live_..., Authorization: ApiKey ws_live_... or X-API-Key.
Not supported: HTTP Basic authentication with a console API key as the password. SolrJ and other clients that default to Basic credentials need a custom header instead.
curl -s "https://api.warpsearch.io/compat/solr/books/select" \
-H "Authorization: Bearer ws_live_..." \
--data-urlencode "q=title:dune AND year:[1960 TO *]" \
--data-urlencode "fq=genre:scifi" \
--data-urlencode "rows=10" \
--data-urlencode "fl=id,title,score"
pysolr takes a prepared requests session:
import pysolr, requests
session = requests.Session()
session.headers["Authorization"] = "Bearer ws_live_..."
solr = pysolr.Solr(
"https://api.warpsearch.io/compat/solr/books",
session=session,
always_commit=True,
)
results = solr.search("title:dune", rows=10)
In SolrJ, build the client on an HTTP client that adds the Authorization header to every request, and set the base URL to https://api.warpsearch.io/compat/solr/books. Query through the select handler (QueryRequest with the default path, or /query).
#Endpoints
| Endpoint | Methods | Notes |
|---|---|---|
/select, /query |
GET, POST | Search. Parameters or a JSON Request API body |
/get |
GET | Lookup by id or ids, with fl |
/update, /update/json |
POST | JSON documents, one document, or command objects |
/update/json/docs |
POST | One document. split and f mappings are rejected |
/schema/fields, /schema/uniquekey |
GET | Read only |
/admin/ping |
GET | Health check |
Role needs follow Solr's split: a viewer searches and gets, an editor also updates and commits, an admin also runs optimize.
#Query parsers and parameters
| Feature | Support |
|---|---|
Standard (Lucene) q |
Fields, AND OR NOT, + -, phrases with slop, ^boost, ^=score, ~ fuzzy, wildcards, /regex/, ranges, Solr date math, [* TO *] |
df, q.op, defType, q.alt |
Exact |
Local params and $param references |
{!type k=v}, _query_, _val_ |
fq |
Several filters, with {!tag=t}, cache, cost |
dismax and edismax |
qf, tie, mm, pf, pf2, pf3, ps, qs, bq, bf, boost. Same documents, summed field scores |
field, term, raw, terms, prefix, bool, simple |
Supported |
func, frange, boost |
Supported |
geofilt, bbox |
Exact. score= is rejected |
knn |
{!knn f=embedding topK=10}[0.1, 0.2, ...], with fq filtering candidates first |
rq={!rerank ...} |
The rerank query is added as a boosted clause. Whole result set is rescored, not just the top reRankDocs |
sort |
Fields, score, functions, geodist(), field(f,min|max). Documents with no value sort last |
start, rows, fl |
Names, globs, score, alias:field |
timeAllowed, TZ, NOW |
Exact. A timeout sets partialResults |
wt |
json only |
Fields are the collection's fields. A field that is not mapped must carry a type suffix in its name such as _t for text, _s for string, _i for integer, _f for float, _d for double or _dt for date, as in the Solr default configset. See Schemas and field types. Queries on the catch-all _text_ field need a real field behind it; set the collection's default fields instead.
Function queries support arithmetic, log, ln, exp, pow, sqrt, abs, min, max, floor, ceil, recip, linear, map, def, field, if, comparisons, logic, ms() and geodist(). rint rounds half up, where Solr rounds half to even, and warns.
Not supported: term and index statistics in functions (
tf,idf,termfreq,docfreq,norm,maxdoc),query(),ord,scale, trigonometric functions, string distance, and string literals.{!ltr},maxscore, join, graph and block-join parsers, and{!collapse}.
Coming soon: exact
dismaxandedismaxscoring (the maximum across fields instead of the sum) and highlighting.
#Faceting and statistics
Classic facets and the JSON Facet API both work.
| Feature | Support |
|---|---|
facet.field |
facet.limit, facet.mincount, facet.missing, facet.offset, per-field f.<field>.*, {!key ex} exclusions |
facet.sort=index |
Exact, up to your plan's facet size. Fails if the field has more values than that |
facet.query, facet.interval |
Exact |
facet.range |
start, end, gap as number or date math, hardend, other, include, mincount |
facet.pivot |
Nested facets with per-bucket stats. Levels must be string or id fields |
stats.field |
min max sum count missing sumOfSquares mean stddev percentiles, tags and exclusions |
| JSON Facet API | terms, query, range, domain (filter, query, excludeTags), nested facet, sort, numBuckets, allBuckets, statistics such as avg, sum, unique, hll, percentile |
group.field, group.query |
One field sort, group.limit, group.offset, group.format=simple, group.main, group.ngroups (approximate, with a warning) |
Counts such as unique(), countDistinct, numBuckets and group.ngroups are approximate, with a warning where Solr would be exact. On numeric and date fields, zero-count terms are not listed, so facet.mincount=0 behaves like 1 with a warning.
Not supported:
facet.prefix,facet.contains,facet.matches,facet.excludeTerms, heatmaps,relatedness(),uniqueBlock(), sub-facets under numeric or text facets, and sorting facets by derived or sketch statistics. Grouping by relevance (the default sort), several sort keys,group.func,group.facetandgroup.truncateare rejected, so set an explicit fieldsortwhen you usegroup=true.
#Updating documents
Send a JSON array of documents, a single document, or command objects:
curl -s "https://api.warpsearch.io/compat/solr/books/update?commit=true" \
-H "Authorization: Bearer ws_live_..." \
-H "Content-Type: application/json" \
-d '[{"id": "1", "title_t": "Dune", "year_i": 1965}]'
{
"add": {"doc": {"id": "2", "title_t": "Dune Messiah"}},
"delete": {"id": "1"},
"commit": {}
}
Supported: add, delete by id, commit, softCommit, commitWithin, overwrite=false and optimize. A document with an existing id replaces the old one. If a document in a request fails, the request fails after the earlier documents were written, as in Solr without a tolerant update chain.
Not supported: delete by query, atomic and in-place updates (
set,inc,add,remove),_version_concurrency, child documents, XML, CSV and javabin bodies, update processor chains,rollback, and document boosts.
#Schema and ping
/schema/fields and /schema/uniquekey are read only. Field types are reported as Solr names: text_general, string, plong, pfloat, pdouble, pdate, location and knn_vector. There is no Schema API for adding fields. Create the collection and its mapping through the console, the REST API, or the Elasticsearch-compatible PUT /{index} call, then point Solr clients at it. /admin/ping returns a Solr-style ping response.
#Response shapes
Search responses follow Solr's JSON: responseHeader (with status, QTime and warnings when there are any), response with numFound, start and docs, and facet_counts, facets, stats and grouped blocks when you ask for them. fl aliases are applied.
#Not supported, summarized
Not supported: highlighting (
hlis accepted with a warning and returns no snippets), spellcheck, suggest, more like this, the terms component, term vectors, clustering, query elevation,cursorMarkdeep paging,expand, joins and nested documents, computed fields and document transformers infl([docid],[explain],[child],geodist()), shape and polygon spatial queries, anddebugoutput (it warns).
For features that have no Solr equivalent here, such as vector and hybrid search, use {!knn} or the other query languages. See Vector search, Hybrid search and Query languages. For limits and error codes, see Limits and errors. If you are migrating, see Migrate from Elasticsearch, OpenSearch or Solr.