# Search settings

> Choose the fields to search and their weights, the fields to filter, facet, and sort by, and how results rank.

Each index has its own settings. Change them on the index's **Search settings** page, or from your server:

```ts
const settings = await products.getSettings()
const saved = await products.replaceSettings({
  ...settings,
  facetFields: ["brand.name", "categories"],
})
console.log(saved.applied) // "fields"
```

`replaceSettings` saves the full settings, so start from `getSettings()` and change what you need. Facet, filter, and sort fields must appear in at least one record first, because their types come from your data.

A new index searches `title` (weight 8) and `brand.name` (weight 4), counts `brand.name` as a facet, and sorts by relevance.

## Settings

```ts
{
  searchableAttributes: [
    { field: "title", weight: 8 },
    { field: "brand.name", weight: 4 },
    { field: "description", weight: 1 },
  ],
  facetFields: ["brand.name", "categories", "inStock"],
  filterFields: ["price"],
  sorts: [
    { id: "relevance", label: "Relevance", field: "relevance", direction: "desc", thenBy: [] },
    { id: "price-asc", label: "Price: low to high", field: "price", direction: "asc", thenBy: [] },
    { id: "newest", label: "Newest", field: "createdAt", direction: "desc", thenBy: [] },
  ],
  defaultSort: "relevance",
  customRanking: [{ field: "popularity", direction: "desc" }],
  synonyms: [["sneakers", "trainers", "running shoes"]],
  typoTolerance: true,
  normalizationProfile: "default-v1",
}
```

### Searchable fields

`searchableAttributes` lists one to five text fields that queries match, each with a weight from 0.1 to 100 (1 by default). A match in a heavier field ranks higher, so give short, precise fields like titles, brands, and SKUs more weight than descriptions.

An index has two short search fields, which hold up to 1 KB of text each, and three long ones, which hold up to 16 KB each. The first two fields of a new index use the short ones; fields added later use long ones while any are free. A record with too much text in a searchable field is rejected with a message naming the field.

To find records by ID, add `objectID` as a searchable field. Its words match exactly, without typos, prefixes, or synonyms.

### Facets and filters

`facetFields` are fields to count values for, such as brands and categories, which also makes them filterable. `filterFields` are fields to filter by without counting values, such as prices. Facets and filters work on text, numbers, and booleans, and on lists of them.

### Sorting

`sorts` are the orders a search can ask for by `id`, besides `relevance`. Each sorts by one field that holds a single value (not a list), `asc` or `desc`; `thenBy` must be empty for now. `defaultSort` is the sort used when a search doesn't choose one. Sort IDs use lowercase letters, digits, `_`, and `-`, and an index has up to eight.

### Custom ranking

`customRanking` orders results that are about equally relevant, within 10% of the best match's score, by up to three fields, such as popularity or stock. Relevance still comes first: a much better match is never pushed down by it.

### Synonyms

`synonyms` are groups of words or phrases that match each other: searching for any of them finds the others, ranked slightly below the word itself. An index has up to 1,000 groups of 2 to 20 terms, each of up to four words.

### Typo tolerance

With `typoTolerance` on (the default), query words also match:

- as prefixes, for words of three or more letters, so `jack` finds `jacket`;
- with one typo in words of four to six letters, and two in longer words;
- with two neighboring letters swapped, so `hsoe` finds `shoe`.

Exact matches rank above prefixes and typos, and numbers always match exactly. Turn it off to match whole words only.

### Text normalization

Searches ignore case and accents, so `cafe` finds `Café`. `normalizationProfile` changes how text is folded:

- `default-v1`: case and accents.
- `icelandic-ascii-v1`: also matches `ð` as `d`, `þ` as `th`, and `æ` as `ae`, for shoppers typing without Icelandic letters.

## How changes apply

Searches keep working while settings change. `applied` in the response says how the change took effect:

| `applied`    | Changes                                                                                                           | When it takes effect                                            |
| ------------ | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| `instant`    | Weights, synonyms, typo tolerance, sort labels and the default sort, and removing or reordering searchable fields | At once                                                         |
| `fields`     | Facet, filter, sort, and custom ranking fields                                                                    | When the save returns: seconds for tens of thousands of records |
| `searchable` | New searchable fields                                                                                             | In the background for large indexes                             |
| `rebuild`    | Text normalization                                                                                                | In the background for large indexes                             |
| `none`       | Nothing changed                                                                                                   |                                                                 |

A `searchable` or `rebuild` change that takes longer than a few seconds continues in the background, with its progress in `rebuild` (also returned by `getSettings`). Searches use the previous settings until it finishes, and writes made meanwhile are included. Wait for it before depending on the new settings:

```ts
const saved = await products.replaceSettings(next)
if (!saved.rebuilt && saved.rebuild) await products.waitForSettings()
```

> **Note:** An index runs one settings change at a time, and a full catalog replacement can't start while one
> runs. Plan large changes around your nightly sync.
