AI Skill Library

Meilisearch & Typesense

Open-source search engines: instant search, typo tolerance, faceting, ranking.

meilisearchtypesensesearchbackend
# Meilisearch & Typesense

## Meilisearch

### Run
```bash
docker run -d --name meilisearch \
  -p 7700:7700 \
  -e MEILI_MASTER_KEY=masterKey \
  getmeili/meilisearch:latest
```

### Node.js SDK
```bash
npm install meilisearch
```
```ts
import { MeiliSearch } from 'meilisearch'
const client = new MeiliSearch({ host: 'http://localhost:7700', apiKey: 'masterKey' })
const index = client.index('products')

// Add documents
await index.addDocuments([
  { id: 1, title: 'iPhone 15', brand: 'Apple', price: 799, tags: ['phone'] },
  { id: 2, title: 'Galaxy S24', brand: 'Samsung', price: 749, tags: ['phone'] },
])

// Search
const results = await index.search('iphone', {
  limit: 10,
  offset: 0,
  filter: 'price < 1000 AND brand = Apple',
  facets: ['brand', 'tags'],
  attributesToHighlight: ['title'],
  sort: ['price:asc'],
})
console.log(results.hits, results.facetDistribution)
```

### Configure settings
```ts
await index.updateSettings({
  searchableAttributes: ['title', 'description', 'brand'],  // order = relevance
  filterableAttributes: ['brand', 'tags', 'price'],
  sortableAttributes: ['price', 'rating'],
  rankingRules: ['words', 'typo', 'proximity', 'attribute', 'sort', 'exactness'],
  typoTolerance: { minWordSizeForTypos: { oneTypo: 4, twoTypos: 8 } },
  synonyms: { 'smartphone': ['phone', 'mobile'], 'tv': ['television'] },
})
```

### React InstantSearch
```tsx
import { InstantSearch, SearchBox, Hits, RefinementList } from 'react-instantsearch'
import { instantMeiliSearch } from '@meilisearch/instant-meilisearch'

const searchClient = instantMeiliSearch('http://localhost:7700', 'searchKey')

<InstantSearch searchClient={searchClient} indexName="products">
  <SearchBox />
  <RefinementList attribute="brand" />
  <Hits hitComponent={({ hit }) => <div>{hit.title}</div>} />
</InstantSearch>
```

---

## Typesense

### Run
```bash
docker run -d --name typesense \
  -p 8108:8108 \
  -v /tmp/typesense:/data \
  typesense/typesense:26.0 \
  --data-dir /data --api-key=xyz --enable-cors
```

### Node.js SDK
```ts
import Typesense from 'typesense'
const client = new Typesense.Client({
  nodes: [{ host: 'localhost', port: 8108, protocol: 'http' }],
  apiKey: 'xyz',
})

// Create collection (schema)
await client.collections().create({
  name: 'products',
  fields: [
    { name: 'title', type: 'string' },
    { name: 'brand', type: 'string', facet: true },
    { name: 'price', type: 'float', facet: true },
    { name: 'embedding', type: 'float[]', num_dim: 1536 },  // vector search
  ],
  default_sorting_field: 'price',
})

// Search
const results = await client.collections('products').documents().search({
  q: 'iphone',
  query_by: 'title,brand',
  filter_by: 'price:<1000',
  facet_by: 'brand,price(ranges:[0,500],[500,1000])',
  sort_by: 'price:asc',
  per_page: 20,
})
```

## Choosing
| | Meilisearch | Typesense | Elasticsearch |
|---|---|---|---|
| Setup | Easy | Easy | Complex |
| Speed | Very fast | Very fast | Fast |
| Scale | Medium | Medium | Large |
| Vector search | Basic | Yes | Yes |
| Use case | Small-Medium apps | Small-Medium apps | Enterprise |

API: /api/skills/meilisearch-typesense