MeiliSearch

Fast and relevant search engine. Instant search, typo tolerance, and multi-language support. Easy setup and developer-friendly.

Search EngineOpen SourceFast SearchReal-timeMulti-languageTypo ToleranceRESTfulAI Search

Server

MeiliSearch

Overview

MeiliSearch is a blazingly fast and user-friendly open-source search engine built in Rust. Featuring sub-50 millisecond search speeds, AI-powered hybrid search, and typo tolerance, it delivers exceptional search experiences for both developers and end-users. As a self-hosted solution, businesses maintain complete control over their data.

Details

MeiliSearch 2024 edition provides next-generation search capabilities including AI-powered hybrid search that combines vector and keyword search, multi-modal search across images, videos, and audio, and multi-index search capabilities. Built with Rust's high-performance architecture, it achieves 50-millisecond search responses where traditional Elasticsearch takes 500+ milliseconds, featuring intuitive developer APIs and flexible self-hosted deployment options.

Key Features

  • AI-Driven Search: Hybrid search combining semantic and full-text search capabilities
  • High Performance: Sub-50 millisecond search response times
  • Typo Tolerance: Returns relevant results even with spelling mistakes
  • Multi-language Support: Comprehensive language support with language-specific optimizations
  • Simple API: Developer-friendly RESTful API design
  • Self-Hosted: Complete data control with flexible deployment options

Pros and Cons

Pros

  • Easy setup with developer-friendly APIs providing high development efficiency
  • Significantly faster search performance compared to Elasticsearch and Algolia
  • Cost reduction and technical freedom through open-source nature
  • Simple access to rich search features (facets, filtering, geosearch)
  • Active community development and support
  • Flexible pricing structure suitable for small to medium businesses

Cons

  • Lacks the massive data processing capabilities of Elasticsearch
  • Smaller plugin ecosystem compared to other mature search engines
  • May underperform Elasticsearch in complex analytical queries
  • Limited enterprise-grade features for large-scale deployments
  • Restricted commercial support options
  • May have limitations for certain advanced customization requirements

Reference Pages

Code Examples

Setup and Installation

# Docker execution
docker run -it --rm \
  -p 7700:7700 \
  -v $(pwd)/meili_data:/meili_data \
  getmeili/meilisearch:v1.5

# macOS installation (Homebrew)
brew install meilisearch

# Linux binary installation
curl -L https://install.meilisearch.com | sh

# Development environment startup
./meilisearch --master-key=yourMasterKey --db-path ./meili_data

# Docker Compose configuration
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  meilisearch:
    image: getmeili/meilisearch:v1.5
    ports:
      - "7700:7700"
    volumes:
      - ./meili_data:/meili_data
    environment:
      - MEILI_MASTER_KEY=yourSecureMasterKey
      - MEILI_DB_PATH=/meili_data
      - MEILI_HTTP_ADDR=0.0.0.0:7700
      - MEILI_LOG_LEVEL=INFO
    restart: unless-stopped
EOF

docker-compose up -d

Index Creation and Document Management

# Create index
curl -X POST 'http://localhost:7700/indexes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "uid": "movies",
    "primaryKey": "id"
  }'

# Add single document
curl -X POST 'http://localhost:7700/indexes/movies/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "id": 1,
    "title": "The Shawshank Redemption",
    "overview": "Two imprisoned men bond over a number of years",
    "genre": ["Drama", "Crime"],
    "release_date": "1994-09-23",
    "duration": 142,
    "rating": 9.3,
    "director": "Frank Darabont",
    "studio": "Columbia Pictures"
  }'

# Bulk add multiple documents
curl -X POST 'http://localhost:7700/indexes/movies/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '[
    {
      "id": 2,
      "title": "The Godfather",
      "overview": "The aging patriarch of an organized crime dynasty transfers control",
      "genre": ["Drama", "Crime"],
      "release_date": "1972-03-24",
      "duration": 175,
      "rating": 9.2,
      "director": "Francis Ford Coppola",
      "studio": "Paramount Pictures"
    },
    {
      "id": 3,
      "title": "The Dark Knight",
      "overview": "Batman begins his war on crime with his first major enemy being Jack Napier",
      "genre": ["Action", "Crime", "Drama"],
      "release_date": "2008-07-18",
      "duration": 152,
      "rating": 9.0,
      "director": "Christopher Nolan",
      "studio": "Warner Bros"
    }
  ]'

# Bulk import from CSV file
curl -X POST 'http://localhost:7700/indexes/movies/documents' \
  -H 'Content-Type: text/csv' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary @movies.csv

# Update document
curl -X PUT 'http://localhost:7700/indexes/movies/documents' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "id": 1,
    "rating": 9.4
  }'

Search Query Implementation

# Basic search
curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "batman"
  }'

# Advanced search options
curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "crime drama",
    "attributesToRetrieve": ["id", "title", "overview", "rating"],
    "attributesToHighlight": ["title", "overview"],
    "attributesToCrop": ["overview"],
    "cropLength": 15,
    "filter": "genre = \"Crime\" AND rating > 8.5",
    "sort": ["rating:desc", "release_date:desc"],
    "facets": ["genre", "director", "studio"],
    "limit": 20,
    "offset": 0
  }'

# Filtering search
curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "",
    "filter": "director = \"Christopher Nolan\" OR director = \"Francis Ford Coppola\"",
    "facets": ["director", "studio", "genre"]
  }'

# Geo search (location-based search)
curl -X POST 'http://localhost:7700/indexes/theaters/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "cinema",
    "filter": "_geoRadius(40.7589, -73.9851, 5000)",
    "sort": ["_geoPoint(40.7589, -73.9851):asc"]
  }'

# Typo tolerance configuration
curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "shawshenk redemtion",
    "matchingStrategy": "all"
  }'

Schema Design and Index Configuration

# Configure searchable attributes
curl -X PUT 'http://localhost:7700/indexes/movies/settings/searchable-attributes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '[
    "title",
    "overview", 
    "director",
    "genre"
  ]'

# Configure filterable attributes
curl -X PUT 'http://localhost:7700/indexes/movies/settings/filterable-attributes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '[
    "genre",
    "director",
    "studio",
    "rating",
    "release_date",
    "_geo"
  ]'

# Configure sortable attributes
curl -X PUT 'http://localhost:7700/indexes/movies/settings/sortable-attributes' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '[
    "rating",
    "release_date",
    "duration",
    "title"
  ]'

# Configure ranking rules
curl -X PUT 'http://localhost:7700/indexes/movies/settings/ranking-rules' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '[
    "words",
    "typo",
    "proximity",
    "attribute",
    "sort",
    "exactness",
    "rating:desc"
  ]'

# Configure synonyms
curl -X PUT 'http://localhost:7700/indexes/movies/settings/synonyms' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "movie": ["film", "cinema", "picture"],
    "director": ["filmmaker", "auteur"],
    "action": ["adventure", "thriller"]
  }'

# Configure typo tolerance
curl -X PUT 'http://localhost:7700/indexes/movies/settings/typo-tolerance' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "enabled": true,
    "minWordSizeForTypos": {
      "oneTypo": 5,
      "twoTypos": 9
    },
    "disableOnWords": ["Batman", "Nolan"],
    "disableOnAttributes": ["director"]
  }'

Performance Optimization

# Check index statistics
curl -X GET 'http://localhost:7700/indexes/movies/stats' \
  -H 'Authorization: Bearer yourMasterKey'

# Monitor tasks
curl -X GET 'http://localhost:7700/tasks' \
  -H 'Authorization: Bearer yourMasterKey'

# Optimize index settings
curl -X PUT 'http://localhost:7700/indexes/movies/settings' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "pagination": {
      "maxTotalHits": 10000
    },
    "faceting": {
      "maxValuesPerFacet": 1000
    },
    "searchCutoffMs": 1500
  }'

# Memory usage configuration (at startup)
export MEILI_MAX_INDEXING_MEMORY="2Gb"
export MEILI_MAX_INDEXING_THREADS=4
./meilisearch

# Production environment configuration
cat > meili.env << 'EOF'
MEILI_DB_PATH=/var/lib/meilisearch/data
MEILI_HTTP_ADDR=0.0.0.0:7700
MEILI_MASTER_KEY=yourProductionMasterKey
MEILI_ENV=production
MEILI_LOG_LEVEL=WARN
MEILI_MAX_INDEXING_MEMORY=4Gb
MEILI_MAX_INDEXING_THREADS=4
MEILI_EXPERIMENTAL_SEARCH_QUEUE_SIZE=2000
EOF

SDK and Framework Integration

// JavaScript/Node.js SDK
import { MeiliSearch } from 'meilisearch'

const client = new MeiliSearch({
  host: 'http://localhost:7700',
  apiKey: 'yourMasterKey'
})

// Create index
const index = await client.createIndex('movies', { primaryKey: 'id' })

// Add documents
const documents = [
  {
    id: 1,
    title: 'The Shawshank Redemption',
    overview: 'Two imprisoned men bond over a number of years',
    genre: ['Drama', 'Crime'],
    rating: 9.3
  }
]

let task = await index.addDocuments(documents)
await index.waitForTask(task.taskUid)

// Perform search
const searchResults = await index.search('shawshank', {
  attributesToHighlight: ['title', 'overview'],
  filter: 'rating > 8.0',
  sort: ['rating:desc'],
  limit: 10
})

console.log(searchResults.hits)

// Advanced search configuration
await index.updateSettings({
  searchableAttributes: ['title', 'overview', 'director'],
  filterableAttributes: ['genre', 'rating', 'release_date'],
  sortableAttributes: ['rating', 'release_date'],
  synonyms: {
    'movie': ['film', 'cinema', 'picture'],
    'director': ['filmmaker', 'auteur']
  }
})
# Python SDK
import meilisearch

client = meilisearch.Client('http://localhost:7700', 'yourMasterKey')

# Create index
index = client.create_index('movies', {'primaryKey': 'id'})

# Add documents
documents = [
    {
        'id': 1,
        'title': 'The Shawshank Redemption',
        'overview': 'Two imprisoned men bond over a number of years',
        'genre': ['Drama', 'Crime'],
        'rating': 9.3
    }
]

task = index.add_documents(documents)
index.wait_for_task(task['taskUid'])

# Perform search
search_results = index.search('shawshank', {
    'attributesToHighlight': ['title', 'overview'],
    'filter': 'rating > 8.0',
    'sort': ['rating:desc'],
    'limit': 10
})

print(search_results['hits'])

# Update settings
index.update_settings({
    'searchableAttributes': ['title', 'overview', 'director'],
    'filterableAttributes': ['genre', 'rating', 'release_date'],
    'sortableAttributes': ['rating', 'release_date'],
    'synonyms': {
        'movie': ['film', 'cinema', 'picture'],
        'director': ['filmmaker', 'auteur']
    }
})

Security and API Key Management

# Create API key
curl -X POST 'http://localhost:7700/keys' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "description": "Search only key for production",
    "actions": ["search"],
    "indexes": ["movies"],
    "expiresAt": "2024-12-31T23:59:59Z"
  }'

# Create read-only key
curl -X POST 'http://localhost:7700/keys' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "description": "Read-only key for analytics",
    "actions": ["search", "documents.get", "indexes.get", "stats.get"],
    "indexes": ["*"],
    "expiresAt": null
  }'

# Create admin key
curl -X POST 'http://localhost:7700/keys' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "description": "Admin key for index management",
    "actions": ["*"],
    "indexes": ["movies", "users"],
    "expiresAt": "2025-06-30T23:59:59Z"
  }'

# List API keys
curl -X GET 'http://localhost:7700/keys' \
  -H 'Authorization: Bearer yourMasterKey'

# SSL/TLS configuration (using Nginx)
cat > /etc/nginx/sites-available/meilisearch << 'EOF'
server {
    listen 443 ssl http2;
    server_name search.example.com;
    
    ssl_certificate /path/to/ssl/certificate.crt;
    ssl_certificate_key /path/to/ssl/private.key;
    
    location / {
        proxy_pass http://localhost:7700;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
EOF

Advanced Features and Hybrid Search

# Configure embedders for AI search
curl -X PUT 'http://localhost:7700/indexes/movies/settings/embedders' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourMasterKey' \
  --data-binary '{
    "huggingface": {
      "source": "huggingFace",
      "model": "sentence-transformers/all-MiniLM-L6-v2",
      "revision": "main",
      "documentTemplate": "{{doc.title}} {{doc.overview}}"
    }
  }'

# Perform hybrid search
curl -X POST 'http://localhost:7700/indexes/movies/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "space adventure movie",
    "hybrid": {
      "semanticRatio": 0.5,
      "embedder": "huggingface"
    },
    "showRankingScore": true
  }'

# Multi-index search
curl -X POST 'http://localhost:7700/multi-search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "queries": [
      {
        "indexUid": "movies",
        "q": "action",
        "limit": 5
      },
      {
        "indexUid": "books",
        "q": "thriller",
        "limit": 5
      }
    ]
  }'

# Federated search
curl -X POST 'http://localhost:7700/indexes/global/search' \
  -H 'Content-Type: application/json' \
  -H 'Authorization: Bearer yourSearchKey' \
  --data-binary '{
    "q": "science fiction",
    "federation": {
      "queries": [
        {
          "indexUid": "movies",
          "weight": 0.8
        },
        {
          "indexUid": "books",
          "weight": 0.6
        },
        {
          "indexUid": "games",
          "weight": 0.4
        }
      ]
    }
  }'

MeiliSearch is a modern search engine that prioritizes speed and simplicity, delivering exceptional performance especially for multi-language content including English and other international languages. It offers an excellent choice for achieving commercial-grade search functionality at low cost while leveraging the benefits of open-source software.