Skip to main content
The optionalWords parameter defines which words in the query are considered optional. By default, all query terms must match for a record to be included in the search results. For example, a search for phone case only returns records where the words phone and case occur in the searchable attributes. Optional words allow for query relaxation. For example, with phone and case as optional words, the same search returns records with the words phone or case. Matches with all words rank higher than matches with only non-optional words.
When using optional words, Algolia performs “double querying”: one query with all terms, and another where optional words are removed. Results are merged and re-ranked.

Usage

  • You can include multiple optional phrases or word sets.
  • Each string is interpreted as a set of optional words. Don’t separate words with commas.
  • This feature increases the response size.
  • There isn’t a hard limit on the number of words, but using too many can slow down getSettings and the Algolia dashboard.

Long queries

If the query contains four or more optional words, the required number of matched words in a record increases for every 1,000 records:
  • If optionalWords has up to 10 words, the required number of matched words increases by 1.
  • If optionalWords has 10 or more words, the required number of matching words is based on the number of optional words divided by 5 (rounded down). For example:
    • For the first 1,000 results, 1 matched word is required.
    • For the next 1,000 results, 4 matched words are needed (the initial 1, plus the calculated increase of 3).

Comparison with removeWordsIfNoResults

Use removeWordsIfNoResults when you want optional behavior only if no results are found. This is more adaptive for unpredictable, user-generated queries.

Comparison with stop words

Stop word removal always ignores common words (words that add no value to a search query, such as “the”, “on”, and “it”)

Examples

Set default list of optional words for all queries

Current API clients

This example sets "blue" and "iphone case" as optional words for all queries. That means, a query for blue iphone case matches records that match either blue, or iphone case, or both.
var response = await client.SetSettingsAsync(
  "INDEX_NAME",
  new IndexSettings
  {
    OptionalWords = new OptionalWords(new List<string> { "blue", "iphone case" }),
  }
);
final response = await client.setSettings(
  indexName: "INDEX_NAME",
  indexSettings: IndexSettings(
    optionalWords: [
      "blue",
      "iphone case",
    ],
  ),
);
response, err := client.SetSettings(client.NewApiSetSettingsRequest(
  "INDEX_NAME",
  search.NewEmptyIndexSettings().SetOptionalWords(search.ArrayOfStringAsOptionalWords(
    []string{"blue", "iphone case"}))))
if err != nil {
  // handle the eventual error
  panic(err)
}
UpdatedAtResponse response = client.setSettings(
  "INDEX_NAME",
  new IndexSettings().setOptionalWords(OptionalWords.of(Arrays.asList("blue", "iphone case")))
);
const response = await client.setSettings({
  indexName: 'theIndexName',
  indexSettings: { optionalWords: ['blue', 'iphone case'] },
});
var response =
  client.setSettings(
    indexName = "INDEX_NAME",
    indexSettings =
      IndexSettings(optionalWords = OptionalWords.of(listOf("blue", "iphone case"))),
  )
$response = $client->setSettings(
    'INDEX_NAME',
    ['optionalWords' => [
        'blue',

        'iphone case',
    ],
    ],
);
response = client.set_settings(
    index_name="INDEX_NAME",
    index_settings={
        "optionalWords": [
            "blue",
            "iphone case",
        ],
    },
)
response = client.set_settings(
  "INDEX_NAME",
  Algolia::Search::IndexSettings.new(optional_words: ["blue", "iphone case"])
)
val response = Await.result(
  client.setSettings(
    indexName = "INDEX_NAME",
    indexSettings = IndexSettings(
      optionalWords = Some(OptionalWords(Seq("blue", "iphone case")))
    )
  ),
  Duration(100, "sec")
)
let response = try await client.setSettings(
    indexName: "INDEX_NAME",
    indexSettings: IndexSettings(optionalWords: SearchOptionalWords.arrayOfString(["blue", "iphone case"]))
)
This example sets "blue" and "iphone case" as optional words for all queries. That means, a query for blue iphone case matches records that match either blue, or iphone case, or both.
IndexSettings settings = new IndexSettings();
settings.OptionalWords = new List
{
  "blue",
  "iphone case"
},

index.SetSettings(settings);
res, err := index.SetSettings(search.Settings{
	OptionalWords: opt.OptionalWords(
		"blue",
		"iphone case",
	),
})
index.setSettings(
  new IndexSettings()
    .setOptionalWords(
      Arrays.asList(
        "blue",
        "iphone case"
      )
    )
);
index
  .setSettings({
    optionalWords: ["blue", "iphone case"],
  })
  .then(() => {
    // done
  });
val settings = settings {
    optionalWords {
        +"blue"
        +"iphone case"
    }
}

index.setSettings(settings)
$index->setSettings([
  'optionalWords' => [
    'blue',
    'iphone case'
  ]
]);
index.set_settings({"optionalWords": ["blue", "iphone case"]})
index.set_settings(
  {
    optionalWords: [
      "blue",
      "iphone case"
    ]
  }
)
client.execute {
  setSettings of "myIndex" `with` IndexSettings(
    optionalWords = Some(Seq(
      "blue",
      "iphone case"
    ))
  )
}
let settings = Settings()
  .set(\.optionalWords, to: ["blue", "iphone case"])

index.setSettings(settings) { result in
  if case .success(let response) = result {
    print("Response: \(response)")
  }
}

Override optional words for the current query

Current API clients

var response = await client.SearchSingleIndexAsync<Hit>(
  "INDEX_NAME",
  new SearchParams(
    new SearchParamsObject
    {
      Query = "query",
      OptionalWords = new OptionalWords(new List<string> { "toyota", "2020 2021" }),
    }
  )
);
final response = await client.searchSingleIndex(
  indexName: "INDEX_NAME",
  searchParams: SearchParamsObject(
    query: "query",
    optionalWords: [
      "toyota",
      "2020 2021",
    ],
  ),
);
response, err := client.SearchSingleIndex(client.NewApiSearchSingleIndexRequest(
  "INDEX_NAME").WithSearchParams(search.SearchParamsObjectAsSearchParams(
  search.NewEmptySearchParamsObject().SetQuery("query").SetOptionalWords(search.ArrayOfStringAsOptionalWords(
    []string{"toyota", "2020 2021"})))))
if err != nil {
  // handle the eventual error
  panic(err)
}
SearchResponse response = client.searchSingleIndex(
  "INDEX_NAME",
  new SearchParamsObject().setQuery("query").setOptionalWords(OptionalWords.of(Arrays.asList("toyota", "2020 2021"))),
  Hit.class
);
const response = await client.searchSingleIndex({
  indexName: 'indexName',
  searchParams: { query: 'query', optionalWords: ['toyota', '2020 2021'] },
});
var response =
  client.searchSingleIndex(
    indexName = "INDEX_NAME",
    searchParams =
      SearchParamsObject(
        query = "query",
        optionalWords = OptionalWords.of(listOf("toyota", "2020 2021")),
      ),
  )
$response = $client->searchSingleIndex(
    'INDEX_NAME',
    ['query' => 'query',
        'optionalWords' => [
            'toyota',

            '2020 2021',
        ],
    ],
);
response = client.search_single_index(
    index_name="INDEX_NAME",
    search_params={
        "query": "query",
        "optionalWords": [
            "toyota",
            "2020 2021",
        ],
    },
)
response = client.search_single_index(
  "INDEX_NAME",
  Algolia::Search::SearchParamsObject.new(query: "query", optional_words: ["toyota", "2020 2021"])
)
val response = Await.result(
  client.searchSingleIndex(
    indexName = "INDEX_NAME",
    searchParams = Some(
      SearchParamsObject(
        query = Some("query"),
        optionalWords = Some(OptionalWords(Seq("toyota", "2020 2021")))
      )
    )
  ),
  Duration(100, "sec")
)
let response: SearchResponse<Hit> = try await client.searchSingleIndex(
    indexName: "INDEX_NAME",
    searchParams: SearchSearchParams.searchSearchParamsObject(SearchSearchParamsObject(
        query: "query",
        optionalWords: SearchOptionalWords.arrayOfString(["toyota", "2020 2021"])
    ))
)
index.Search(new Query("")
{
    OptionalWords = new List
    {
      "toyota",
      "2020 2021"
    },
});
res, err := index.Search(
"query",

  OptionalWords: opt.OptionalWords(
    "toyota",
    "2020 2021",
  },
})
index.search(
  new Query("query")
    .setOptionalWords(
      Arrays.asList(
        "toyota",
        "2020 2021"
      )
    )
);
index
  .search("query", {
    optionalWords: ["toyota", "2020 2021"],
  })
  .then(({ hits }) => {
    console.log(hits);
  });
val query = query("query") {
    optionalWords {
        +"toyota"
        +"2020 2021"
    }
}

index.search(query)
$results = $index->search('query', [
  'optionalWords' => [
    'toyota',
    '2020 2021'
  ]
]);
results = index.search("query", {"optionalWords": ["toyota", "2020 2021"]})
results = index.search(
  "query",
  {
    optionalWords: [
      "toyota",
      "2020 2021"
    ]
  }
)
client.execute {
  search into "myIndex" query Query(
    query = Some("query"),
    optionalWords = Some(Seq(
      "toyota",
      "2020 2021"
    ))
  )
}
let query = Query(query: "query")
query.optionalWords = ["toyota", "2020 2021"]

index.search(query, completionHandler: { (res, error) in
  print(res)
})
Last modified on May 19, 2026