On Opensolr, one Solr request can rank results by the words of a search and by its meaning at the same time. The {!hybrid} query parser, built by Opensolr and installed on the servers that run site search, runs a keyword query and a vector query side by side and merges their scores for every document.
01 · The request
q={!hybrid lexical=$lexicalQuery vector=$vectorQuery mode=union alpha=0.85 topN=500}
lexicalQuery={!edismax qf="title^0.2 description^0.05 uri^0.01 text^0.01 text_t^0.01" mm="2<65% 4<50% 8<40%" v=$uq}
uq=solar panels for a small roof
vectorQuery={!knn f=embeddings topK=500}[0.0123,-0.0456,0.0789, ... 1,024 numbers]
The words of the visitor go in their own parameter, uq, and the keyword query reads them with v=$uq. Solr then takes them as plain text: a quote, a brace or a colon typed in the search box cannot change the query. Send the request as a POST: the vector is too long for a URL.
02 · The parameters
| Parameter | What it does | Opensolr sends |
|---|---|---|
lexical | The keyword sub-query, usually edismax. | $lexicalQuery |
vector | The vector sub-query: {!knn f=embeddings topK=N}[vector]. | $vectorQuery |
mode | union: documents found by either side. keywords_required: only documents that match the words, ranked by words and meaning. meaning_required: only documents among the vector candidates, lifted by the words. intersection: only documents found by both. | union |
alpha | The weight of meaning, from 0 to 1. Both scores are normalized within the candidates, then score = alpha × meaning + (1 − alpha) × words. | 0.85 |
topN | How many candidates each side brings before the merge. | 500 |
03 · The defaults come from Search Tuning
The values above are the defaults. Search Tuning in the WebCrawler tab of your index changes them for your hosted search page: the field weights give qf, Minimum Match gives mm, Semantic and Lexical Balance gives alpha (alpha = 1 − the lexical weight), Vector Pool gives topK and topN, and Search Mode gives mode. Lexical Only is not a mode of the parser: the page then sends the keyword query alone. The Query Inspector of your search page shows your own values.
04 · The vector
vectorQuery needs the meaning vector of the search: 1,024 numbers made by the same model that made the vectors of your documents. Get it from the embed endpoint with is_query=1; it answers a JSON array of numbers. Documents get their vectors only when the plan of the index owner includes AI (what your index needs); without a vector, send the keyword query alone.
05 · Where it runs
{!hybrid} exists only on the Opensolr servers that run site search: the regions marked for it when you create an index. On any other Solr server the request fails with an unknown query parser error.
06 · Next
The same request in PHP, Node.js, Python and curl, with the fallback to words.
embed_and_search makes the vector and searches in a single API call.
What hybrid search does for your visitors.