🌐 Detecting your location…

So implementieren Sie die Suche in einer Web-App mit Meilisearch im Jahr 2026

⏱️5 min read  ·  952 words

Meilisearch ist eine schnelle Open-Source-Suchmaschine, die eine sofortige, typotolerante Suche mit minimalem Setup ermöglicht – eine einfachere Alternative zu Elasticsearch für die meisten Anwendungen. Dieser Leitfaden fügt einer Web-App von der Installation bis zur Frontend-Integration eine leistungsstarke Suche hinzu.

Warum Meilisearch?

  • Sofortsuche: Antworten unter 50 ms, Ergebnisse während der Eingabe von
  • Tippfehlertoleranz: Findet Ergebnisse trotz Rechtschreibfehlern sofort
  • Einfache Einrichtung: Viel einfacher als Elasticsearch – sinnvolle Standardeinstellungen
  • Open Source: Selbsthosting und kostenlos, mit Cloud-Option
  • Große Relevanz: Gute Ergebnisse ohne aufwändiges Tuning

Meilisearch ausführen

# Run with Docker (easiest)
docker run -d --name meilisearch -p 7700:7700 \
  -e MEILI_MASTER_KEY="your-master-key" \
  getmeili/meilisearch:latest

# Verify it's running
curl http://localhost:7700/health
# {"status":"available"}

Indizierungsdaten

npm install meilisearch
import { MeiliSearch } from 'meilisearch';

const client = new MeiliSearch({
  host: 'http://localhost:7700',
  apiKey: 'your-master-key',
});

// Create an index and add documents
const index = client.index('products');

await index.addDocuments([
  { id: 1, name: 'Wireless Keyboard', category: 'Peripherals', price: 89 },
  { id: 2, name: 'Mechanical Keyboard', category: 'Peripherals', price: 129 },
  { id: 3, name: 'USB-C Hub', category: 'Accessories', price: 45 },
]);
// Each document needs a unique 'id' field (or configure the primary key)

Einfache Suche

// Simple search - typo-tolerant automatically
const results = await index.search('keybord');   // note the typo
console.log(results.hits);
// Still finds both keyboards despite the misspelling

// Search with options
const results = await index.search('keyboard', {
  limit: 20,
  attributesToHighlight: ['name'],   // highlight matches
  attributesToRetrieve: ['id', 'name', 'price'],
});

Durchsuchbare und filterbare Felder konfigurieren

// Set which fields are searchable (and their priority order)
await index.updateSearchableAttributes([
  'name',        // highest priority
  'category',
  'description',
]);

// Set filterable attributes for faceted filtering
await index.updateFilterableAttributes(['category', 'price']);

// Set sortable attributes
await index.updateSortableAttributes(['price']);

Filtern und Facettieren

// Filter results
const results = await index.search('keyboard', {
  filter: 'category = "Peripherals" AND price < 100',
});

// Faceted search - get counts per category
const results = await index.search('keyboard', {
  facets: ['category'],
});
console.log(results.facetDistribution);
// { category: { Peripherals: 2, Accessories: 0 } }

// Sort results
const results = await index.search('keyboard', {
  sort: ['price:asc'],
});

Frontend-Integration (Sofortsuche)

// React example - search as you type
import { useState, useEffect } from 'react';
import { MeiliSearch } from 'meilisearch';

// Use a SEARCH-ONLY key on the frontend, never the master key
const client = new MeiliSearch({
  host: 'https://search.example.com',
  apiKey: 'search-only-key',   // scoped key with search-only permissions
});

function Search() {
  const [query, setQuery] = useState('');
  const [results, setResults] = useState([]);

  useEffect(() => {
    if (!query) { setResults([]); return; }

    const timer = setTimeout(async () => {
      const res = await client.index('products').search(query, { limit: 10 });
      setResults(res.hits);
    }, 150);   // debounce - avoid a request on every keystroke

    return () => clearTimeout(timer);
  }, [query]);

  return (
    <div>
      <input value={query} onChange={e => setQuery(e.target.value)}
             placeholder="Search..." />
      <ul>
        {results.map(hit => <li key={hit.id}>{hit.name}</li>)}
      </ul>
    </div>
  );
}

Den Index synchron halten

// Update the index when your data changes
async function onProductCreated(product) {
  await index.addDocuments([product]);
}

async function onProductUpdated(product) {
  await index.updateDocuments([product]);   // upserts by id
}

async function onProductDeleted(productId) {
  await index.deleteDocument(productId);
}
// Call these from your app's create/update/delete handlers to keep
// search results current with your database.

Sicherheit: Verwenden Sie bereichsbezogene API-Schlüssel

// NEVER expose the master key to the frontend.
// Create a search-only key for client use:
const searchKey = await client.createKey({
  actions: ['search'],
  indexes: ['products'],
  expiresAt: null,
});
// Use searchKey.key on the frontend - it can only search, not modify

Häufig gestellte Fragen

F: Meilisearch oder Elasticsearch?
A: Meilisearch bietet Einfachheit, sofortige Suche und Tippfehlertoleranz bei minimaler Einrichtung – ideal für die meisten Apps. Elasticsearch für sehr umfangreiche, komplexe Analysen und erweiterte Funktionen. Zum Hinzufügen einer Suche zu einer typischen Web-App ist Meilisearch weitaus einfacher und ausreichend.

F: Meilisearch oder PostgreSQL-Volltextsuche?
A: Die PostgreSQL-Suche vermeidet zusätzliche Infrastruktur (nutzt Ihre vorhandene Datenbank) und verarbeitet viele Apps gut. Meilisearch bietet eine bessere Tippfehlertoleranz, eine sofortige Such-UX und eine sofort einsatzbereite Facettierung, allerdings auf Kosten der Ausführung eines separaten Dienstes und der Synchronisierung von Daten. Wählen Sie basierend darauf, ob die UX-Qualität der Suche den zusätzlichen Service rechtfertigt.

F: Wie halte ich den Suchindex mit meiner Datenbank synchron?
A: Aktualisieren Sie den Meilisearch-Index, wenn sich Ihre Daten ändern – rufen Sie addDocuments/updateDocuments/deleteDocument über die Create/Update/Delete-Handler Ihrer App auf. Führen Sie für die Massensynchronisierung regelmäßig eine Neuindizierung durch. Der Index ist von Ihrer Datenbank getrennt, daher müssen Sie sie synchron halten.

F: Ist die Suche über das Frontend sicher?
A: Ja, wenn Sie einen API-Schlüssel mit eingeschränkter Suchfunktion verwenden (niemals den Hauptschlüssel). Erstellen Sie einen Schlüssel nur mit der Aktion „Suchen“ für bestimmte Indizes und verwenden Sie diesen im Frontend. Der Hauptschlüssel darf nur serverseitig bleiben, da er Daten ändern kann.

F: Kann Meilisearch große Datensätze verarbeiten?
A: Es verarbeitet Millionen von Dokumenten gut und bietet eine gute Leistung. Für extrem große (Hunderte Millionen) oder komplexe Analysen ist Elasticsearch möglicherweise besser geeignet. Für die meisten Web-Apps – E-Commerce, Inhalte, SaaS – lässt sich Meilisearch mehr als ausreichend skalieren.

Fazit

Meilisearch macht das Hinzufügen einer schnellen, typfehlertoleranten Suche zu einer Web-App bemerkenswert einfach – für die meisten Anforderungen weitaus einfacher als Elasticsearch. Der Aufbau:Führen Sie Meilisearch (Docker) aus, indizieren Sie Ihre Dokumente, konfigurieren Sie durchsuchbare und filterbare Attribute und integrieren Sie die Sofortsuche im Frontend mit einer entprellten Eingabe und einem bereichsbezogenen Nur-Such-API-Schlüssel. Halten Sie den Index synchron, indem Sie ihn über die Datenänderungshandler Ihrer App aktualisieren. Sie erhalten eine Suche in weniger als 50 ms, Tipptoleranz, Facettierung und Filterung sofort einsatzbereit und mit minimaler Konfiguration. Für E-Commerce, Content-Websites und die meisten SaaS-Apps bietet Meilisearch ein hervorragendes Sucherlebnis ohne die Komplexität einer aufwändigeren Suchinfrastruktur – eine gute Wahl, wenn Sie schnell eine qualitativ hochwertige Such-UX wünschen.

MD Rafikul Islam

Written by

MD Rafikul Islam is a software developer and the editor of TechPulse. He writes about developer tooling, hardware, and the practical decisions that come up in day-to-day engineering work — which laptop to buy, which framework to commit to, why a build broke at 2am. He tests the tools he writes about and says plainly when something is not worth the money. Corrections and corrections requests are welcome at rony.yf25@gmail.com.

✍️ Leave a Comment

Your email address will not be published. Required fields are marked *

🌐 Read in:🇬🇧 English🇩🇪 Deutsch🇧🇷 Português🇸🇦 العربية🇮🇳 हिन्दी🇧🇩 বাংলা