How search understands a query

OrbSearch reads what a query names in the shop's own words, such as a category, a color or a width, and searches only the words that are left.

A shopper who types "graues Sofa bis 220 cm" (grey sofa up to 220 cm) means a page, not five words. OrbSearch reads what the query names before it searches, and the answer says what it read.

What the query named

The answer's resolution holds what the query named: a category, filters, the text left over, and whether the query is complete:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=graues%20Sofa%20bis%20220%20cm' \
  | jq -c '.resolution, [.sections[] | select(.type == "product") | .hits[].entity]'
200 · 23 ms · release b25a6aaa
{"category":"wohnen/sofas","filters":{"color":"grey","width":{"lte":220}},"text":"","complete":true}
["product:SOFA-ASKA-2","product:SOFA-NIKO-SCHLAF"]

"Sofa" named the category wohnen/sofas (living/sofas), "graues" the color grey and "bis 220 cm" a width. No word is left as text, so the listing holds the two grey sofas up to 220 cm. Such a query names a whole page, so the answer also carries a redirect to it (URLs and redirects).

Reference: resolution

Where the names come from

Every name comes from the shop itself, and the trace says which entry each word matched:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=graues%20Sofa%20bis%20220%20cm&debug=1' \
  | jq -c '.trace.steps[] | select(.step == "resolve") | .detections[] | {words, entry, pattern}'
200 · 13 ms · release b25a6aaa
{"words":"Sofa","entry":"the title \"Sofas\" of the category wohnen/sofas","pattern":null}
{"words":"bis 220 cm","entry":"width up to 220 cm","pattern":"width-at-most"}
{"words":"graues","entry":"the label \"Grau\" of the color grey","pattern":null}
Trace10.07 ms
  1. resolve“Sofa” → category wohnen/sofas · “bis 220 cm” → width ≤ 220 · “graues” → color grey

OrbSearch 1.36 msMeilisearch 8.71 ms

A query is read with four kinds of entry:

  • The catalog's own words: category titles, brand names and the labels of attribute values, such as "Grau" (grey), also in their inflected forms ("graues").
  • Aliases a value lists in attributes.json, such as "gray" for grey.
  • Synonyms: "couch" names the sofas through the group of couch and sofa, and its detection names that group in synonym.
  • Patterns: the shop's phrases, such as bis {width} cm, {seats}-sitzer (seater) or "im Angebot" (on sale), and built-in ones for a price or a size with its unit.

Values are read only for attributes marked detect_in_query. A word that names two things stays text, and the step's kept says why. Merchants add synonyms and patterns.

Reference: resolve · Detection · detect_in_query

Take back what the query named

A shopper who meant the word, not the filter, removes its chip. Send the detection back in dismissed, and its words stay text however often the query is sent again:

Terminal
curl -s http://127.0.0.1:7800/v1/search -H 'Content-Type: application/json' \
  -d '{ "query": "graues Sofa", "dismissed": [{ "field": "color", "value": "grey" }] }' \
  | jq -c '.resolution'
200 · 4.3 ms · release b25a6aaa
{"category":"wohnen/sofas","text":"graues","complete":false}

"graues" is searched as a word again, within the sofas. Without a value, every detection of the field is taken back, such as { "field": "width" }.

Only POST carries dismissed. The search page keeps it in its URL as ignore, such as /suche?q=graues+Sofa&ignore=color:grey, which /v1/resolve reads back as dismissed (URLs and redirects).

Reference: dismissed

How the words match

The words left as text are searched rarest first. Where no product holds every word, the words most products hold give way:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=Lund%20Samt&debug=1' \
  | jq -r '.trace.steps[] | select(.step == "rank") | .sections[] | select(.type == "product")
      | .hits[] | .entity, (.why[] | select(.because.kind == "text") | .sentence)'
200 · 12 ms · release b25a6aaa
product:SOFA-LUND-3
Found by 1 of the query's 2 words, without typos, in title.

No product is both the Lund sofa and "Samt" (velvet). Three products hold "Samt" and one holds "Lund", so the search finds the Lund sofa instead of every velvet product. Products that hold every word still rank first. The sections beside the products drop words from the end instead.

Which fields a type's words are looked for in, and how many typos they forgive, is set per type in types.json.

Reference: rank · search · typos

Other languages

The shop's own words resolve in every locale it writes them in. The same query in English names the same page:

Terminal
curl -s 'http://127.0.0.1:7800/v1/search?query=grey%20sofa%20up%20to%20220%20cm&locale=en' | jq -c '.resolution'
200 · 6.2 ms · release b25a6aaa
{"category":"wohnen/sofas","filters":{"color":"grey","width":{"lte":220}},"text":"","complete":true}

The built-in knowledge covers German and English only: inflected forms, color words, and the price and quantity bounds such as "bis" and "under". A shop in another language writes what it needs as synonyms and patterns.

Reference: patterns.json · synonyms.json

Next

On this page