docs-site/content/30.1/api/synonyms.md
:::warning Breaking Change in v30 When you upgrade to v30, all existing collection-specific synonym definitions will be automatically migrated to the new synonym sets format. Your searches will continue working without any hiccups, but you have to use the new API and client methods for reading and writing to the synonym definitions. If self-hosting, perform a snapshot before upgrading for the Synonyms & Overrides to be migrated to v30. :::
:::warning API Key Actions Updated
Since the synonym API route changed from /collections/{collection}/synonyms to /synonym_sets, API keys scoped to synonyms:* actions will not grant access to the new synonym set endpoints (resulting in 401 Unauthorized). You need to create new API keys using synonym_sets:* actions instead. Since there is no update endpoint for API keys, you will need to create new keys and then delete the old ones. See the full list of Synonym Set actions.
:::
The synonym sets feature allows you to define search terms that should be considered equivalent. For example: when you define a synonym for sneaker as shoe, searching for sneaker will now return all records with the word shoe in them, in addition to records with the word sneaker.
Typesense supports two types of synonyms within synonym sets:
One-way synonyms: Defining the words iphone and android as one-way synonyms of smart phone will cause searches for smart phone to return documents containing iphone or android or both.
Multi-way synonyms: Defining the words blazer, coat and jacket as multi-way synonyms will cause searches for any one of those words (eg: coat) to return documents containing at least one of the words in the synonym set (eg: records with blazer or coat or jacket are returned).
:::tip Precedence When using Synonym Sets and Overrides together, Overrides are handled first since the rules can contain instructions to replace the query. Synonym Sets will then work on the modified query. :::
:::tip Locale-specific synonyms
When a synonym has a locale specified, it will only be applied when searching fields with a matching locale. If no locale is specified for a synonym, it will be applied globally. This helps manage cases where the same word has different meanings across languages.
:::
:::tip Phrase Match Queries & Filtering Synonyms are not triggered when using Phrase Search or Filtering, by design.
So for eg, "Site Reliability" will not return results containing Infrastructure even if they are defined as multi-way synonyms, because of the double quotes around "Site Reliability" which makes it a phrase search. So only documents that contain that exact full phrase are returned, without any synonym matches.
Also, synonyms are only applied to the tokens in the q search parameter, and not to any tokens in the filter_by parameter. For eg, if you define a multi-way synonym for abc <> xyz and use filter_by: title:=abc, it will only match documents where title=abc, not title=xyz, because filtering is designed to be similar to a SQL WHERE condition to do a structured query and synonyms don't apply to filters.
:::
synonymSet = {
items: [
{
id: 'coat-synonyms',
synonyms: ['blazer', 'coat', 'jacket'],
},
],
}
// Creates/updates a synonym set called `clothing-synonyms`
client.synonymSets('clothing-synonyms').upsert(synonymSet)
$synonymSet = [
"items" => [
[
"id" => "coat-synonyms",
"synonyms" => ["blazer", "coat", "jacket"]
]
]
];
# Creates/updates a synonym set called `clothing-synonyms`
$client->synonymSets['clothing-synonyms']->upsert($synonymSet);
synonym_set = {
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}
# Creates/updates a synonym set called `clothing-synonyms`
client.synonym_sets["clothing-synonyms"].upsert(synonym_set)
synonym_set = {
"items" => [
{
"id" => "coat-synonyms",
"synonyms" => ["blazer", "coat", "jacket"]
}
]
}
# Creates/updates a synonym set called `clothing-synonyms`
client.synonym_sets["clothing-synonyms"].upsert(synonym_set)
SynonymItemSchema synonymItem = new SynonymItemSchema();
synonymItem.setId("coat-synonyms");
synonymItem.addSynonymsItem("blazer").addSynonymsItem("coat").addSynonymsItem("jacket");
SynonymSetCreateSchema synonymSet = new SynonymSetCreateSchema();
synonymSet.addItemsItem(synonymItem);
// Creates/updates a synonym set called `clothing-synonyms`
client.synonymSets("clothing-synonyms").upsert(synonymSet);
synonymItem := &api.SynonymItemSchema{
ID: "coat-synonyms",
Synonyms: []string{"blazer", "coat", "jacket"},
}
synonymSet := &api.SynonymSetCreateSchema{
Items: []*api.SynonymItemSchema{synonymItem},
}
// Creates/updates a synonym set called `clothing-synonyms`
client.SynonymSets("clothing-synonyms").Upsert(context.Background(), synonymSet)
curl "http://localhost:8108/synonym_sets/clothing-synonyms" -X PUT \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}'
{
"name": "clothing-synonyms",
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}
synonymSet = {
items: [
{
id: 'smart-phone-synonyms',
root: 'smart phone',
synonyms: ['iphone', 'android'],
},
],
}
// Creates/updates a synonym set called `tech-synonyms`
client.synonymSets('tech-synonyms').upsert(synonymSet)
$synonymSet = [
"items" => [
[
"id" => "smart-phone-synonyms",
"root" => "smart phone",
"synonyms" => ["iphone", "android"]
]
]
];
# Creates/updates a synonym set called `tech-synonyms`
$client->synonymSets['tech-synonyms']->upsert($synonymSet);
synonym_set = {
"items": [
{
"id": "smart-phone-synonyms",
"root": "smart phone",
"synonyms": ["iphone", "android"]
}
]
}
# Creates/updates a synonym set called `tech-synonyms`
client.synonym_sets["tech-synonyms"].upsert(synonym_set)
synonym_set = {
"items" => [
{
"id" => "smart-phone-synonyms",
"root" => "smart phone",
"synonyms" => ["iphone", "android"]
}
]
}
# Creates/updates a synonym set called `tech-synonyms`
client.synonym_sets["tech-synonyms"].upsert(synonym_set)
SynonymItemSchema synonymItem = new SynonymItemSchema();
synonymItem.setId("smart-phone-synonyms");
synonymItem.addSynonymsItem("iphone").addSynonymsItem("android");
synonymItem.setRoot("smart phone");
SynonymSetCreateSchema synonymSet = new SynonymSetCreateSchema();
synonymSet.addItemsItem(synonymItem);
// Creates/updates a synonym set called `tech-synonyms`
client.synonymSets("tech-synonyms").upsert(synonymSet);
synonymItem := &api.SynonymItemSchema{
ID: "smart-phone-synonyms",
Root: pointer.String("smart phone"),
Synonyms: []string{"iphone", "android"},
}
synonymSet := &api.SynonymSetCreateSchema{
Items: []*api.SynonymItemSchema{synonymItem},
}
// Creates/updates a synonym set called `tech-synonyms`
_, _ = client.SynonymSets("tech-synonyms").Upsert(context.Background(), synonymSet)
curl "http://localhost:8108/synonym_sets/tech-synonyms" -X PUT \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
"items": [
{
"id": "smart-phone-synonyms",
"root": "smart phone",
"synonyms": ["iphone", "android"]
}
]
}'
{
"name": "tech-synonyms",
"items": [
{
"id": "smart-phone-synonyms",
"root": "smart phone",
"synonyms": ["iphone", "android"]
}
]
}
PUT ${TYPESENSE_HOST}/synonym_sets/:synonymSetName
| Parameter | Required | Description |
|---|---|---|
| items | yes | Array of synonym items, where each item contains the synonym definitions. |
| items.id | yes | Unique identifier for the synonym item. |
| items.synonyms | yes | Array of words that should be considered as synonyms. |
| items.root | no | For 1-way synonyms, indicates the root word that words in the synonyms parameter map to. |
| items.locale | no | Locale for the synonym. If specified, the synonym will only be applied when searching a field that has a matching locale. If not specified, the synonym will be applied globally. |
| items.symbols_to_index | no | By default, special characters are dropped from synonyms. Use this attribute to specify which special characters should be indexed as is. |
After creating a synonym set, be sure to link it to a collection. Read more in the documentation on linking synonym sets with collections.
We can retrieve a single synonym set.
<Tabs :tabs="['JavaScript','PHP','Python','Ruby','Java','Go','Shell']"> <template v-slot:JavaScript>client.synonymSets('clothing-synonyms').retrieve()
$client->synonymSets['clothing-synonyms']->retrieve();
client.synonym_sets["clothing-synonyms"].retrieve()
client.synonym_sets["clothing-synonyms"].retrieve()
SynonymSet synonymSet = client.synonymSets("clothing-synonyms").retrieve();
client.SynonymSets("clothing-synonyms").Retrieve(context.Background())
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/synonym_sets/clothing-synonyms"
{
"name": "clothing-synonyms",
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}
GET ${TYPESENSE_HOST}/synonym_sets/:synonymSetName
List all synonym sets.
<Tabs :tabs="['JavaScript','PHP','Python','Ruby','Java','Go','Shell']"> <template v-slot:JavaScript>client.synonymSets().retrieve()
$client->synonymSets->retrieve();
client.synonym_sets.retrieve()
client.synonym_sets.retrieve()
List<SynonymSetSchema> synonymSets = client.synonymSets().retrieve();
client.SynonymSets().Retrieve(context.Background())
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/synonym_sets"
[
{
"name": "clothing-synonyms",
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}
]
GET ${TYPESENSE_HOST}/synonym_sets
Delete a synonym set.
<Tabs :tabs="['JavaScript','PHP','Python','Ruby','Java','Go','Shell']"> <template v-slot:JavaScript>client.synonymSets('clothing-synonyms').delete()
$client->synonymSets['clothing-synonyms']->delete();
client.synonym_sets["clothing-synonyms"].delete()
client.synonym_sets["clothing-synonyms"].delete()
SynonymSetDeleteSchema result = client.synonymSets("clothing-synonyms").delete();
client.SynonymSets("clothing-synonyms").Delete(context.Background())
curl "http://localhost:8108/synonym_sets/clothing-synonyms" -X DELETE \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
{
"name": "clothing-synonyms"
}
DELETE ${TYPESENSE_HOST}/synonym_sets/:synonymSetName
{
"name": "products",
"fields": [
{
"name": "name",
"type": "string"
}
],
"synonym_sets": ["clothing-synonyms", "tech-synonyms"]
}
curl "http://localhost:8108/collections/products" -X PATCH \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
-d '{
"synonym_sets": ["clothing-synonyms", "tech-synonyms"]
}'
Synonym sets can be used in search parameters dynamically. The search operation will look for synonyms in:
For example, if the collection products is linked to clothing-synonyms synonym set, the following search request will use synonyms from clothing-synonyms, tech-synonyms, and electronics-synonyms:
curl "http://localhost:8108/collections/products/documents/search?q=controller&query_by=name&synonym_sets=tech-synonyms,electronics-synonyms" -X GET \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
synonymSetItem = {
root: 'smart phone',
synonyms: ['iphone', 'android'],
}
// Creates/updates a synonym set called `tech-synonyms`
client.synonymSets('tech-synonyms').items('smart-phone-synonyms').upsert(synonymSetItem)
$synonymSetItem = [
'root' => 'smart phone',
'synonyms' => ['iphone', 'android'],
];
$client->synonymSets['tech-synonyms']->items['smart-phone-synonyms']->upsert($synonymSetItem);
synonymSetItem = {
"root": "smart phone",
"synonyms": ["iphone", "android"],
}
# Creates/updates a synonym set called `tech-synonyms`
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].upsert(synonymSetItem)
synonymSetItem = {
"root" => "smart phone",
"synonyms" => ["iphone", "android"],
}
# Creates/updates a synonym set called `tech-synonyms`
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].upsert(synonymSetItem)
SynonymItemSchema synonymSetItem = new SynonymItemSchema();
synonymSetItem.setId("smart-phone-synonyms");
synonymSetItem.addSynonymsItem("iphone").addSynonymsItem("android");
synonymSetItem.setRoot("smart phone");
client.synonymSets("tech-synonyms").items("smart-phone-synonyms").upsert(synonymSetItem);
synonymItem := &api.SynonymItemSchema{
ID: "smart-phone-synonyms",
Root: pointer.String("smart phone"),
Synonyms: []string{"iphone", "android"},
}
// Creates/updates a synonym set called `tech-synonyms`
client.SynonymSets("tech-synonyms").Items("smart-phone-synonyms").Upsert(context.Background(), synonymItem)
curl "http://localhost:8108/synonym_sets/tech-synonyms/items/smart-phone-synonyms" -X PUT \
-H "Content-Type: application/json" \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" -d '{
"root": "smart phone",
"synonyms": ["iphone", "android"]
}'
PUT ${TYPESENSE_HOST}/synonym_sets/:synonymSetName/items/:id
client.synonymSets('tech-synonyms').items('smart-phone-synonyms').retrieve()
$client->synonymSets['tech-synonyms']->items['smart-phone-synonyms']->retrieve();
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].retrieve()
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].retrieve()
SynonymItemSchema synonymItem = client.synonymSets("tech-synonyms").items("smart-phone-synonyms").retrieve();
synonymItem, err := client.SynonymSets("tech-synonyms").Items("smart-phone-synonyms").Retrieve(context.Background())
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/synonym_sets/tech-synonyms/items/smart-phone-synonyms"
GET ${TYPESENSE_HOST}/synonym_sets/:synonymSetName/items/:id
client.synonymSets('tech-synonyms').items().retrieve()
$client->synonymSets['tech-synonyms']->items()->retrieve();
client.synonym_sets['tech-synonyms'].items().retrieve()
client.synonym_sets['tech-synonyms'].items().retrieve()
SynonymItemSchema synonymItem = client.synonymSets("tech-synonyms").items().retrieve();
synonymItem, err := client.SynonymSets("tech-synonyms").Items().Retrieve(context.Background())
curl -H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}" \
"http://localhost:8108/synonym_sets/tech-synonyms/items"
GET ${TYPESENSE_HOST}/synonym_sets/:name/items
client.synonymSets('tech-synonyms').items('smart-phone-synonyms').delete()
$client->synonymSets['tech-synonyms']->items['smart-phone-synonyms']->delete();
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].delete()
client.synonym_sets['tech-synonyms'].items['smart-phone-synonyms'].delete()
client.synonymSets("tech-synonyms").items("smart-phone-synonyms").delete();
client.SynonymSets("tech-synonyms").Items("smart-phone-synonyms").Delete(context.Background())
curl "http://localhost:8108/synonym_sets/tech-synonyms/items/smart-phone-synonyms" -X DELETE \
-H "X-TYPESENSE-API-KEY: ${TYPESENSE_API_KEY}"
DELETE ${TYPESENSE_HOST}/synonym_sets/:synonymSetName/items/:id
:::tip Automatic Migration
All existing synonyms from previous versions have been automatically migrated to the new synonym sets format. Each collection's synonyms are now stored in a synonym set with the same name as the collection, postfixed by *_synonyms_index (e.g. products_synonyms_index).
:::
API Endpoints:
/collections/{collection}/synonyms/*/synonym_sets/*Data Structure:
Collection Association:
synonym_sets fieldSearch Usage:
Before (v29 and earlier):
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
After (v30):
{
"name": "products",
"items": [
{
"id": "coat-synonyms",
"synonyms": ["blazer", "coat", "jacket"]
}
]
}
The new API provides better organization, reusability across collections, and more flexible search-time synonym application.