Synonyms

Introduction

See the legacy documentation if you’re looking for the deprecated way to configure synonyms via index settings

Synonyms tell the engine about sets of words and expressions that should be considered equal with regard to textual relevance. The Synonyms API makes it possible to manage a large set of synonyms for an index and its replicas. You can also create synonyms manually from an index configuration’s Synonyms tab.

Understanding synonyms

The term synonym refers to a way of doing query expansion: a method for considering one search term as the equivalent of other terms. Depending on the problem you are trying to solve, different types of synonyms will yield better results.

Synonym records are represented by a JSON object and uniquely identified by an objectID, just like regular index records. All synonym records have a type attribute. Here’s an overview of the different synonym record types.

Note that the engine does not expand the words defined as synonyms. If you want both the singular and plural forms of a word to be considered synonyms of other words, you’ll have to include both forms in your synonym sets. You do not need to add synonyms if you only want to make sure the engine considers singular and plural forms of words to be equivalent in the query: just use the ignorePlural setting.

(Regular) Synonyms

Regular synonyms are the most common. They are defined by a comma-separated list of words that will be considered equivalent by the engine. For example: tv, television, tv set. The type attribute value is simply synonym.

Using this synonym record, a user’s search for “tv” will return records that contain the text “television” or “tv set”.

JSON representation

{
   "objectID": "NAME",
   "type": "synonym",
   "synonyms":[  
      "tv",
      "television",
      "tv set"
   ]
}

One-way synonyms

One-way synonyms allow you to define alternative words for a search term which are not synonyms to each other.

Let’s take an example. When a user searches for “tablet”, you want them to be able to find iPads and Galaxy Note tablets alike, but you might not want Android tablets to show up when they search for “iPad”.

To do this, you would create a one-way synonym record between tablet (as input) and ipad, galaxy note (as synonyms). When the user types in “tablet”, records containing “iPad” and “Galaxy Note” will be returned. However records containing only “tablet” or “Galaxy Note” won’t be returned if he searches for “iPad”.

JSON representation

{  
   "objectID": "NAME",
   "type": "oneWaySynonym",
   "input": "tablet",
   "synonyms":[  
      "ipad",
      "galaxy note"
   ]
}

Alternative corrections

Alternative corrections are just like one-way synonyms, but they allow you to account for one or two typos when an alternative is matched, thus impacting the ranking of the matched records via the typo criterion in the ranking formula.

This construct can be used to make sure common misspellings are taken into account when they fall outside of the typo-tolerance rules, or when you want to take into account alternative words for a search term but with a lower ranking in the results.

To reuse the previous example, you could define tablet as input and ipad as synonym in the same way but with an alternative correction type.

The engine would then account for one or two typos for records containing “iPad” when the user types in “tablet”, thus giving priority in the results to records that actually contain the word “tablet”.

Alternative corrections do not support multi-word corrections yet, so galaxy note from previous example cannot be used here.

JSON representation

Here, the type value is either altCorrection1 or altCorrection2, depending on whether the correction implies a 1 or 2 typo penalty respectively.

{  
   "objectID": "NAME",
   "type": "altCorrection1|altCorrection2",
   "word": "tablet",
   "corrections":[  
      "ipad"
   ]
}

Placeholders

Placeholders allow you to define tokens that can take any value from a list of words that you define. Use tokens in records when you want to match different possible values at this position.

For instance, this record uses a <Street> placeholder (placeholders need to be wrapped in angle brackets):

{
  "address": "589 Howard <Street>"
}

The record could be found when searching for “Howard Street” or “Howard St.” by defining the Street placeholders as a possible equivalent for ["Street", "St"].

JSON representation

{  
   "objectID": "NAME",
   "type": "placeholder",
   "placeholder": "<Street>",
   "replacements": ["street", "st"]
}

Managing synonyms

Using the dashboard

See the Synonyms tab of the index configuration:

Synonyms 1

Adding synonyms

Add synonyms of any type by clicking on the “Add” button just above the synonyms list on the right. The modal view that opens allows you to choose the type of synonym record you want to add. The other fields will change depending on this choice.

Type: Synonym

Synonyms 2

Available fields:

  • Synonyms: enter a comma-separated list of words or expressions that should be considered equivalent.
Type: One-way Synonym

Synonyms 3

Available fields:

  • Search Term: the query part that should be expanded to other alternatives (“tablet”, in our example of the previous section).
  • Alternatives: A comma-separated list of alternative words/expressions that should be considered equivalent to the search term.
Type: Alternative Correction

Synonyms 4

Available fields:

  • Search Term: the query part that should be expanded to other alternatives (“tablet”, in our example of the previous section).
  • Typo: the number of typos (1 or 2) that should be accounted for when the search term is matched to one of the alternatives.
  • Corrections: A comma-separated list of alternative words that should be considered equivalent to the search term.

Note that only single-word expressions are allowed for both Search Term and Corrections. No spaces please!

Type: Placeholder

Synonyms 5

Available fields:

  • Placeholder: the token that should be identified in records as a placeholder. It must be enclosed in angle brackets. For example: <street>.
  • Replacements: a comma-separated list of expressions that are allowed in place of the placeholder. Any query part matching one of the replacements will also match the placeholder.
Forward to replica indices

Any synonyms that you create on an index can be automatically propagated to replica indices. This is the default. Unless you want the synonyms to apply to the current index only, just leave the box checked!

Importing synonyms from a file

If you have a lot of synonyms, perhaps sourced by a merchandising team or pulled from an external dictionary, you probably don’t want to add them one by one.

An easier method is to upload an entire file of synonyms at once. Click the “Upload” button at the top right corner of the Synonyms tab and this modal view will open:

Synonyms 6

Two data formats are supported: JSON and CSV. Note: CSV is limited to regular synonyms.

JSON

The file must contain an array of newline-delimited JSON objects. Each object must include:

  • A unique objectID value that identifies the synonym record. It will not be generated if it’s missing.
  • A type value. Options are synonym, oneWaySynonym, altCorrection1, altCorrection2, and placeholder.
  • All other fields required by the chosen type as described in the earlier sections.
CSV

A CSV file can only be used to import regular synonyms (type is synonym). The file must contain one set of comma-separated synonyms per line.

Forward to replica indices

Keep this box checked to forward synonyms to all replica indices.

Deleting synonyms

If you want to remove all synonyms from an index, click the “Delete All” button and this modal will appear:

Synonyms 7

Confirm the deletion by entering the name of the index. This operation cannot be undone. Use the “Forward to replica indices” checkbox to propagate the deletion to all replica indices.

To delete a specific synonym record, click the Trash can icon in the “Actions” column of the synonyms list.

Synonyms 8

Editing synonyms

Click the edit button in the “Actions” column of the synonyms list to edit synonyms. The dialog that opens is identical to the synonym creation dialog described above.

Synonyms 9

Searching synonyms

Finding a specific synonym record can be tedious if you have a lot of them. To address this, the dashboard allows you to search through synonyms and also filter by type.

Using an API client

Backward compatibility

Synonyms were originally set via the index settings, and a Get Settings call would return all synonyms sets as part of the setting’s JSON data.

This behavior has been kept to maintain backward compatibility. If you do not want synonyms to be included in settings, add version=2 to the request as a query parameter:

GET /1/indexes/{indexName}/settings?getVersion=2

All our API clients have been updated to include this new query parameter, so you won’t be able to recover the synonyms from settings anymore with them. You must use the new synonyms search method described below to get all the synonyms.

Until you switch to this new Synonyms API, you can still set synonyms via settings.

Adding synonyms

There are two ways to add synonyms to an index: individually, or as a batch operation if you have multiple records to add at a time.

The examples below use regular synonyms. Please refer to Understanding synonyms to find the correct representations for other synonym types.

Note that in all cases, you must provide an objectID value for each synonym record. The engine will not automatically generate one and you will get an error.

One synonym record

This method saves a single synonym record into the index.

In this example, we specify true to forward the creation to replica indices. By default the behavior is to save only on the specified index.

index.saveSynonym({
  objectID: 'a-unique-identifier',
  type: 'synonym',
  synonyms: ['car', 'vehicle', 'auto']
}, { forwardToSlaves: true }, function(err, content) {
  if(err)
  {
    console.error(err);
  }
});
index.save_synonym('a-unique-identifier', {
  :objectID => 'a-unique-identifier',
  :type => 'synonym',
  :synonyms => ['car', 'vehicle', 'auto']
}, true)
index.save_synonym({
  'objectID': 'a-unique-identifier',
  'type': 'synonym',
  'synonyms': ['car', 'vehicle', 'auto']
}, 'a-unique-identifier', True)
<?php
$index->saveSynonym("a-unique-identifier", array(
  "objectID" => "a-unique-identifier",
  "type" => "synonym",
  "synonyms" => array("car", "vehicle", "auto")
), true);
index.saveSynonym("a-unique-identifier", new Synonym()
           .setSynonyms(Arrays.asList("car", "vehicle", "auto")), true);
client.execute {
save synonym Synonym("a-unique-identifier", Seq("car", "vehicle", "auto")) inIndex "index_name" and forwardToReplicas
}
index.SaveSynonym("a-unique-identifier", JObject.parse(@"{ ""objectID"": ""a-unique-identifier"", ""type"": ""synonym"", ""synonyms"": [""car"", ""vehicle"", ""auto""] }"), true);
uniqueID := "a-unique-identifier"
synonym := algoliasearch.NewSynonym(uniqueID, []string{
    "car", "vehicle", "auto",
})
res, err := index.AddSynonym(uniqueID, synonym, true)
Multiple synonym records

Use the batch method to create a large number of synonyms at once, forward them to replica indices if desired, and optionally replace all existing synonyms on the index with the content of the batch using the replaceExistingSynonyms parameter.

You should always use replaceExistingSynonyms to atomically replace all synonyms on a production index. This is the only way to ensure the index always has a full list of synonyms to use during the indexing of the new list.

// Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
index.batchSynonyms([{
  objectID: 'a-unique-identifier',
  type: 'synonym',
  synonyms: ['car', 'vehicle', 'auto']
}, {
  objectID: 'another-unique-identifier',
  type: 'synonym',
  synonyms: ['street', 'st']
}], { forwardToSlaves: true, replaceExistingSynonyms: true }, function(err, content) {
  if(err)
  {
    console.error(err);
  }
});
# Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
index.batch_synonyms([{
  :objectID => 'a-unique-identifier',
  :type => 'synonym',
  :synonyms => ['car', 'vehicle', 'auto']
}, {
  :objectID => 'another-unique-identifier',
  :type => 'synonym',
  :synonyms => ['street', 'st']
}], true, true)
# Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
index.batch_synonyms([{
  'objectID': 'a-unique-identifier',
  'type': 'synonym',
  'synonyms': ['car', 'vehicle', 'auto']
}, {
  'objectID': 'another-unique-identifier',
  'type': 'synonym',
  'synonyms': ['street', 'st']
}], True, True)
<?php
// Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
$index->batchSynonyms(array(array(
  "objectID" => "a-unique-identifier",
  "type" => "synonym",
  "synonyms" => array("car", "vehicle", "auto")
), array(
  "objectID" => "another-unique-identifier",
  "type" => "synonym",
  "synonyms" => array("street", "st")
)), true, true);
// Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
index.batchSynonyms(Arrays.asList(
      new Synonym()
           .setObjectID("a-unique-identifier")
           .setSynonyms(Arrays.asList("car", "vehicle", "auto")), 
      new Synonym()
           .setObjectID("another-unique-identifier")
           .setSynonyms(Arrays.asList("street", "st"))
), true, true);
// Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
client.execute {
save synonyms Seq(Synonym("a-unique-identifier", Seq("car", "vehicle", "auto")), Synonym("another-unique-identifier", Seq("street", "st"))) inIndex "index_name" and forwardToReplicas and replaceExistingSynonyms
}
index.BatchSynonyms(new object[] {JObject.parse(@"{ ""objectID"": ""a-unique-identifier"", ""type"": ""synonym"", ""synonyms"": [""car"", ""vehicle"", ""auto""] }"), JObject.parse(@"{ ""objectID"": ""another-unique-identifier"", ""type"": ""synonym"", ""synonyms"": [""street"", ""st""] }")}, true, true);
// Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
res, err := index.BatchSynonyms([]algoliasearch.Synonym{
    algoliasearch.NewSynonym("a-unique-identifier", []string{"car", "vehicle", "auto"}),
    algoliasearch.NewSynonym("another-unique-identifier", []string{"street", "st"}),
}, true, true)

Deleting synonyms

Delete specific synonym records is supported, as is clearing the entire list of synonyms from an index.

Delete one synonym record

Use the normal index delete method to delete synonyms, specifying the objectID of the synonym record you want to delete. Forward the deletion to replica indices by setting the forwardToSlaves parameter to true.


// Delete and forward to replicas
index.deleteSynonym('a-unique-identifier', { forwardToSlaves: true }, function(err, content) {
  if(err)
  {
    console.error(err);
  }
});
# Delete and forward to replicas
index.delete_synonym('a-unique-identifier', true)
# Delete and forward to replicas
index.delete_synonym('a-unique-identifier', True)
<?php
// Delete and forward to replicas
$index->deleteSynonym("a-unique-identifier", true);
// Delete and forward to replicas
index.deleteSynonym("a-unique-identifier", true);
// Delete and forward to replicas
client.execute {
    delete synonym "a-unique-identifier" from "index_name" and forwardToReplicas
}
// Delete and forward to replicas
index.DeleteSynonym("a-unique-identifier", true);
// Delete and forward to replicas
res, err := index.DeleteSynonym("a-unique-identifier", true)
Clear all synonyms

This is a convenience method to delete all synonyms at once. It should not be used on a production index to then push a new list of synonyms: there would be a short period of time during which the index would have no synonyms at all. To atomically replace all synonyms of an index, use the batch method with the replaceExistingSynonyms parameter set to true.

// Clear synonyms and forward to replicas
index.clearSynonyms({ forwardToSlaves: true }, function(err, content) {
  if(err)
  {
    console.error(err);
  }
});
# Clear synonyms and forward to replicas
index.clear_synonyms(true)
# Clear synonyms and forward to replicas
index.clear_synonyms(True)
<?php
// Clear synonyms and forward to replicas
$index->clearSynonyms(true);
// Clear synonyms and forward to replicas
index.clearSynonyms(true);
// Clear synonyms and forward to replicas
client.execute {
    clear synonyms of index "index_name" and forwardToReplicas
}
// Clear synonyms and forward to replicas
index.ClearSynonyms(true);
// Clear synonyms and forward to replicas
res, err := index.ClearSynonyms(true)

Editing synonyms

Updating the value of a specific synonym record is the same as creating one. Make sure you specify the same objectID used to create the record and the synonyms will be updated.

When updating multiple synonyms in a batch call (but not all synonyms), make sure you set replaceExistingSynonyms to false (or leave it out, false is the default value). Otherwise, the entire synonym list will be replaced only partially with the records in the batch update.

Searching for synonyms

Search for synonym records by their objectID or by the text they contain. Both methods are covered here.

Search for a single synonym record
index.getSynonym('a-unique-identifier', function(err, content) {
  if(err)
  {
    console.error(err);
  }
  var synonym = content;
});
synonym = index.get_synonym('a-unique-identifier')
synonym = index.get_synonym('a-unique-identifier')
<?php
$synonym = $index->getSynonym("a-unique-identifier");
Optional<AbstractSynonym> synonym = index.getSynonym("a-unique-identifier");
var synonym: Future[Synonym] = client.execute {
	get synonym "a-unique-identifier" from "index_name"
}
JObject synonym = index.GetSynonym("a-unique-identifier");
synonym, err := index.GetSynonym("a-unique-identifier")
Search/browse all synonyms

Search for synonym records similar to how you’d search normally. Accepted search parameters:

  • query: the actual search query to find synonyms. Use an empty query to browse all the synonyms of an index.
  • type: restrict the search to a specific type of synonym. Use an empty string to search all types (default behavior). Multiple types can be specified using a comma-separated list or an array.
  • page: the page to fetch when browsing through several pages of results. This value is zero-based.
  • hitsPerPage: the number of synonyms to return for each call. The default value is 100.
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
index.searchSynonyms({
  query: 'street',
  type: 'synonym,oneWaySynonym',
  page: 1,
  hitsPerPage: 10
}, function(err, content) {
  if(err)
  {
    console.error(err);
  }
  console.log(content.hits);
});
# Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
results = index.search_synonyms('street', {
  :type => ['synonym', 'oneWaySynonym'],
  :page => 1,
  :hitsPerPage => 10
})
# Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
results = index.search_synonyms('street', ['synonym', 'oneWaySynonym'], 1, 10)
<?php
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
$results = $index->searchSynonyms("street", array("synonym", "oneWaySynonym"), 1, 10);
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
SearchSynonymResult results = index.searchSynonyms(new SynonymQuery("street").setTypes(Arrays.asList("synonym", "one_way")).setPage(1).setHitsPerPage(10));
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
var results = client.execute {
    search synonyms of "index_name" query QuerySynonyms(query = "street", types = Some(Seq(SynonymType.synonym, SynonymType.oneWaySynonym)), page = Some(1), hitsPerPage = Some(10))
}
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
JObject results = index.SearchSynonyms("street", new Index.SynonymType[] {Index.SynonymType.SYNONYM, Index.SynonymType.SYNONYM_ONEWAY }, 1, 10);
// Searching for "street" in synonyms and one-way synonyms; fetch the second page with 10 hits per page
synonyms, err := index.SearchSynonyms("street", []string{"synonym", "oneWaySynonym"}, 1, 10)