Synonyms
Tell OrbSearch which words mean the same, so a shopper who types "couch" finds the sofas.
Shoppers say "couch" where the shop says "sofa". A synonym tells search that the words mean the same, so either one finds the sofas. Here are three entries of the home store's German dictionary, one of each kind:
curl -s -H "Authorization: Bearer $key" $api/synonyms \
| jq -r '.dictionaries[] | select(.locale == "de") | .entries[]
| select(.id | IN("de/groups/0", "de/one_way/2", "de/never/0")) | "\(.id) \(.summary)"'de/groups/0 sofa and couch find each other.
de/one_way/2 läufer finds teppich, not the other way round.
de/never/0 sessel and sofa are never merged.- A group holds words that find each other.
- A one-way entry leads its first word to the others only: "Läufer" (runner) finds the rugs, but "Teppich" (rug) finds no runners.
- A never entry keeps look-alike words apart, such as "Sessel" (armchair) and "Sofa". It changes no search.
Each entry's id is its place in synonyms.json, which a change names. Synonyms are always on, with no condition and no schedule.
Reference: groups · one_way · never · GET /api/v1/synonyms
A synonym names what its partner names
A word with a synonym also names what its partner names. "Sofa" is the title of the category Sofas, so "couch" names it too, and so does a compound that ends in a synonym:
for q in couch tischlampe; do
curl -s "http://127.0.0.1:7800/v1/search?query=$q&debug=1" \
| jq -r '.trace.steps[] | select(.step == "resolve") | .detections[].entry'
done"couch", a synonym of "sofa", and "sofa" is the title "Sofas" of the category wohnen/sofas
"tischlampe" ends in "lampe", a synonym of "leuchte", and "leuchte" is the title "Leuchten" of the category leuchten"Couch" leads to the sofa page wohnen/sofas. "Tischlampe" (table lamp) is in no entry, but its last part "lampe" is grouped with "leuchte" (light), which names the category Leuchten. The detection names its entry in synonym, such as de/groups/0, so the trace shows which entry decided.
Reference: resolve · Detection
Add a synonym
A shopper searched "Kanapee", an old word for sofa, and found nothing. Add it in a draft, which shoppers see once you publish it.
Search → Synonyms lists one language's entries, and your first change starts the draft. Type kanapee, sofa on the line on top, and it shows what each word finds now and what the line clashes with:


A word is in one group at most, so the line offers Add “kanapee” there, which joins the group of sofa and couch. A line without a clash goes in with Enter; One way makes its first word find the others only, and words a never entry keeps apart go in only with Add anyway.
The publish bar above the list says how the draft goes live, here within moments and without a rebuild, beside Publish and Discard. A search that finds nothing in the Playground or Insights offers Add a synonym with its words on this line.
Start a draft with the store's export, then add the entry. "sofa" is in a group already, so the add is refused with the entry that holds it:
draft=$(curl -s -X POST -H "Authorization: Bearer $key" -H 'Content-Type: application/x-ndjson' \
--data-binary @tests/fixtures/home/catalog.jsonl "$api/imports?name=catalog.jsonl" | jq -r .import.id)
version=$(curl -s -H "Authorization: Bearer $key" $api/imports/$draft | jq -r .version)
jq -n --arg version "$version" '{version: $version, locale: "de", entries: [{kind: "group", words: ["kanapee", "sofa"]}]}' \
| curl -s -H "Authorization: Bearer $key" -H 'Content-Type: application/json' -d @- $api/imports/$draft/synonyms \
| jq -c '.refused[].conflicts[]'{"id":"taken","word":"sofa","entry":"de/groups/0","words":["sofa","couch"],"sentence":"“sofa” is in the group sofa, couch already."}Add the word to that group instead. A PATCH replaces the entry's words:
jq -n --arg version "$version" '{version: $version, entry: {kind: "group", words: ["sofa", "couch", "kanapee"]}}' \
| curl -s -X PATCH -H "Authorization: Bearer $key" -H 'Content-Type: application/json' -d @- \
$api/imports/$draft/synonyms/de/groups/0 \
| jq -r '.synonyms.dictionaries[] | select(.locale == "de") | .entries[0].summary'sofa, couch and kanapee find each other.Open the search page for "kanapee" with the draft's files in place of the live ones:
body=$(curl -s -H "Authorization: Bearer $key" $api/imports/$draft | jq '{url: "/suche?q=kanapee", files}')
curl -s -H "Authorization: Bearer $key" -H 'Content-Type: application/json' -d "$body" $api/preview/page \
| jq -c '.location, [.results.sections[] | select(.type == "product") | .hits[].entity]'"/wohnen/sofas?from=kanapee"
["product:SOFA-ASKA-2","product:SOFA-LUND-3","product:SOFA-NIKO-SCHLAF","product:SOFA-VIDAR-ECK"]The search page /suche (search) sends "kanapee" to the sofa page with all four sofas. Ask how the draft goes live, then publish it with POST $api/imports/$draft/publish, or discard it:
curl -s -H "Authorization: Bearer $key" $api/imports/$draft/publication | jq -r .course.sentence
curl -s -X DELETE -H "Authorization: Bearer $key" $api/imports/$draft | jq -r .stateGoes live within moments: synonyms.json changed only settings the engine applies without reindexing.
discardedA write on a draft that changed since its version is refused with 409. POST .../synonyms/check answers what the panel's line shows, without writing.
Reference: POST .../synonyms · PATCH .../synonyms/{synonym} · POST .../synonyms/check · POST /api/v1/preview/page
A draft that changes only synonyms goes live as settings, within moments and without a rebuild (Releases).
Traps and limits
- Words are folded. Entries are lowercased, and "Weiß" and "weiss" (white) are one word, in an entry as in a search.
neverguards edits only. It refuses an added or changed entry that merges its words, unless the write saysdespite_never. Asynonyms.jsonwritten whole keeps such a group, and the list names the clash in itsconflicts.- Each language has its own dictionary. A locale reads its own, else that of its shorter tag:
de-CHreadsde, as the list'sreadssays. - A compound counts by its last part. An entry for "lampe" reaches "Tischlampe" too.
- A preview shows what a synonym names, not what it finds in text. The engine keeps the live synonyms until you publish, so "kanapee" previews through the sofa category, while a synonym for a word in product texts shows once live.
Reference: despite_never · SynonymList
Next
- Patterns: turn a phrase such as "bis 220 cm" into a filter.
- How search understands a query: everything a query can name.
- Releases: draft, preview, publish and roll back.