Thomas Pawlitzki

PostgreSQL-Volltextsuche vs. Elasticsearch – wann die Datenbank reicht

BLOGPostgreSQL-Volltextsuchevs. Elasticsearch – wann7. Juli 2026 · Thomas PawlitzkiPostgreSQLElasticsearchOpenSearchpawlitzki.dev

Suchfunktionen in PostgreSQL mit pg_trgm, tsvector und Fuzzystrmatch – und wann Elasticsearch oder OpenSearch die bessere Wahl ist. Mit Code-Beispielen und Entscheidungsmatrix.

PostgreSQL-Volltextsuche vs. Elasticsearch – wann die Datenbank reicht

Suchfunktionen sind aus modernen Webanwendungen nicht wegzudenken. Die Frage ist nur: Zieht man eine dedizierte Suchmaschine wie Elasticsearch oder OpenSearch, oder reichen die Bordmittel der bereits verwendeten PostgreSQL-Datenbank?

Die Antwort hängt stark von den Anforderungen ab. Dieser Artikel zeigt, was PostgreSQL mit tsvector, pg_trgm, fuzzystrmatch und pgvector kann, wo die Grenzen liegen und wann ein dedizierter Suchserver die richtige Wahl ist.

PostgreSQL-Bordmittel für die Suche

PostgreSQL bringt drei leistungsstarke Erweiterungen für verschiedene Suchszenarien mit, die in der Standardinstallation verfügbar sind – kein zusätzlicher Dienst, keine Betriebskomplexität.

1. Volltextsuche mit tsvector / tsquery

Die Volltextsuche arbeitet auf Wortebene: Sie zerlegt Text in Lexeme (Wortstämme) und kann nach Wortformen suchen.

mermaid
flowchart LR
  Text["'Die Hunde laufen'"] --> parser["Parser<br/><small>Worttrennung</small>"]
  parser --> w1["'die'"]
  parser --> w2["'hunde'"]
  parser --> w3["'laufen'"]
  w1 --> sw["Stopwort<br/><small>wird verworfen</small>"]
  w2 --> stemming["Stemming<br/><small>hunde → hund</small>"]
  w3 --> stemming2["Stemming<br/><small>laufen → lauf</small>"]
  stemming --> vector["tsvector: 'hund':1 'lauf':2"]
  stemming2 --> vector
  style sw fill:#f99,color:#000
  style vector fill:#6a6,color:#fff
CREATE TABLE artikel (
  id SERIAL PRIMARY KEY,
  titel TEXT,
  inhalt TEXT,
  suchvektor TSVECTOR
    GENERATED ALWAYS AS (
      to_tsvector('german', titel || ' ' || inhalt)
    ) STORED
);

CREATE INDEX idx_suche ON artikel USING GIN (suchvektor);

INSERT INTO artikel (titel, inhalt) VALUES
  ('Die Datenbank und ihre Performance',
   'Die Performance einer Datenbank hängt von vielen Faktoren ab.'),
  ('Auto fahren auf der Autobahn',
   'Auf der Autobahn mit dem Auto zu fahren macht Spaß.'),
  ('Hunde laufen im Park',
   'Die Hunde laufen jeden Morgen durch den Park.');

-- Volltextsuche: findet Artikel 1 (enthält "Datenbank" UND "Performance")
SELECT titel FROM artikel
WHERE suchvektor @@ to_tsquery('german', 'Datenbank & Performance');

-- to_tsquery('german', 'Datenbank & Performance')
-- → sucht nach Lexemen: 'datenbak' & 'perform'
-- "Datenbank" → Lexem "datenbak" ✓
-- "Performance" → Lexem "perform" ✓

Der tsvector normalisiert Wörter: Aus "läuft", "lief", "gelaufen" wird der gemeinsame Stamm "lauf". Die to_tsquery-Funktion unterstützt & (UND), | (ODER) und ! (NICHT). Der GIN-Index macht die Suche auch auf Millionen Datensätzen schnell.

-- ODER-Suche: findet Artikel mit "Auto" ODER "Hund"
SELECT titel FROM artikel
WHERE suchvektor @@ to_tsquery('german', 'Auto | Hund');

-- NICHT-Suche: findet Artikel mit "Auto", aber NICHT "Autobahn"
SELECT titel FROM artikel
WHERE suchvektor @@ to_tsquery('german', 'Auto & !Autobahn');

Grenzen: Keine Tippfehlertoleranz („Datenbak" findet „Datenbank" nicht), keine Teilwortsuche („auto" findet nicht „Autobahn"), keine phonetische Ähnlichkeit („Meier" ≠ „Meyer").

2. Trigramm-Suche mit pg_trgm

pg_trgm zerlegt Text in Dreierbuchstaben-Gruppen (Trigrams) und ermittelt die Ähnlichkeit über die Überlappung dieser Trigrams.

mermaid
flowchart LR
  Wort["'Autobahn'"] --> trigram["Trigramm-Bildung"]
  trigram --> t1["' au'"]
  trigram --> t2["'aut'"]
  trigram --> t3["'uto'"]
  trigram --> t4["'tob'"]
  trigram --> t5["'oba'"]
  trigram --> t6["'bah'"]
  trigram --> t7["'ahn'"]
  trigram --> t8["'hn '"]
  t1 --> set["Trigramm-Set<br/><small>{' au','aut','uto',<br/>'tob','oba','bah',<br/>'ahn','hn '}</small>"]
  t2 --> set
  t3 --> set
  t4 --> set
  t5 --> set
  t6 --> set
  t7 --> set
  t8 --> set
  style set fill:#6a6,color:#fff
CREATE EXTENSION IF NOT EXISTS pg_trgm;

CREATE INDEX idx_trgm_titel ON artikel USING GIN (titel gin_trgm_ops);
CREATE INDEX idx_trgm_inhalt ON artikel USING GIN (inhalt gin_trgm_ops);

-- Tippfehlertoleranz: "Autobahn" vs "Autoban"
-- similarity('Autobahn', 'Autoban') → 0.78 (78 % Übereinstimmung)
SELECT titel, similarity(titel, 'Autoban') AS aehnlichkeit
FROM artikel
WHERE titel % 'Autoban'
ORDER BY aehnlichkeit DESC;

-- Expliziter Schwellwert (statt default 0,3)
SELECT titel, similarity(titel, 'Autoban') AS aehnlichkeit
FROM artikel
WHERE similarity(titel, 'Autoban') > 0.5
ORDER BY aehnlichkeit DESC;

-- show() zeigt alle Trigrams eines Strings an
SELECT show_trgm('Autobahn');
-- → {"  a"," au",aut,bah,hn ,oba,oto,tob,uto}

-- show_limit() und set_limit() steuern den Schwellwert
SELECT set_limit(0.4);
-- Teilwortsuche: ILIKE nutzt den pg_trgm-Index
-- Findet "Auto" auch in "Autobahn" oder "Automatik"
SELECT titel FROM artikel WHERE titel ILIKE '%auto%';
-- Gewichtete Sortierung: pg_trgm + tsvector kombinieren
SELECT titel,
  similarity(titel, 'Autoban')     AS trigramm_aehnlichkeit,
  ts_rank(suchvektor,
    to_tsquery('german', 'Auto'))  AS volltext_relevanz
FROM artikel
WHERE titel % 'Autoban'
   OR suchvektor @@ to_tsquery('german', 'Auto')
ORDER BY trigramm_aehnlichkeit DESC;

Der %-Operator und die similarity()-Funktion arbeiten mit einem Schwellwert (standardmäßig 0,3). pg_trgm liefert echte Tippfehlertoleranz und ermöglicht mit ILIKE auch Teilworttreffer – ohne dass der Text vorher tokenisiert werden muss.

3. Phonetische Suche mit fuzzystrmatch

fuzzystrmatch bietet Algorithmen für die klangbasierte Ähnlichkeitssuche – nützlich für Namenssuche, bei der Schreibvarianten häufig sind.

CREATE EXTENSION IF NOT EXISTS fuzzystrmatch;

-- === Soundex ===
-- Kodiert Wörter nach ihrem Klang (Buchstabe + 3 Ziffern)
SELECT soundex('Meyer');  -- M600
SELECT soundex('Meier');  -- M600
SELECT soundex('Maier');  -- M600
-- Alle drei klingen gleich → gleicher Soundex-Code

SELECT soundex('Meyer') = soundex('Meier'); -- true
SELECT soundex('Schmidt') = soundex('Schmitt'); -- true

-- === Levenshtein ===
-- Minimale Anzahl an Edit-Operationen (Einfügen, Löschen, Ersetzen)
SELECT levenshtein('Hund', 'Hund');   -- 0 (identisch)
SELECT levenshtein('Hund', 'Hunt');   -- 1 (ein Buchstabe vertauscht)
SELECT levenshtein('Hund', 'Hunde');  -- 1 (ein Buchstabe fehlt)
SELECT levenshtein('Schmidt', 'Schmitt'); -- 2 (2 Buchstaben differenz)

-- === Metaphone (deutscher Metaphon) ===
-- Moderner und sprachsensitiver als Soundex
SELECT metaphon('Schmidt');  -- SMT
SELECT metaphon('Schmitt');  -- SMT
SELECT metaphon('Schmidt') = metaphon('Schmitt'); -- true

-- === Praktische Namenssuche ===
CREATE TABLE kunden (
  id SERIAL PRIMARY KEY,
  vorname TEXT,
  nachname TEXT
);

INSERT INTO kunden (vorname, nachname) VALUES
  ('Thomas', 'Schmidt'),
  ('Tomas',  'Schmitt'),
  ('Tom',    'Smith');

-- Finde "Thomas Schmidt" trotz Schreibvarianten
SELECT vorname, nachname,
  levenshtein(vorname, 'Thomas')  AS vorname_distanz,
  levenshtein(nachname, 'Schmidt') AS nachname_distanz,
  metaphon(nachname) = metaphon('Schmidt') AS klang_gleich
FROM kunden
WHERE metaphon(nachname) = metaphon('Schmidt')
   OR levenshtein(nachname, 'Schmidt') <= 2;
mermaid
flowchart LR
  Input["'Schmidt'"] --> soundex["Soundex<br/><small>S532</small>"]
  Input --> metaphon["Metaphon<br/><small>SMT</small>"]
  Input2["'Schmitt'"] --> soundex2["Soundex<br/><small>S532</small>"]
  Input2 --> metaphon2["Metaphon<br/><small>SMT</small>"]
  soundex --> eq1["S532 = S532 ✅"]
  metaphon --> eq2["SMT = SMT ✅"]
  soundex2 --> eq1
  metaphon2 --> eq2
  style eq1 fill:#6a6,color:#fff
  style eq2 fill:#6a6,color:#fff

4. Alles kombinieren: Universelle Suchfunktion

Die wahre Stärke von PostgreSQL liegt darin, alle Verfahren in einer Abfrage zu vereinen:

-- Universelle Suchfunktion
CREATE OR REPLACE FUNCTION suche_artikel(suchbegriff TEXT)
RETURNS TABLE(titel TEXT, score FLOAT8) AS $$
BEGIN
  RETURN QUERY
  SELECT a.titel,
    (
      -- Volltext-Treffer (höchste Gewichtung)
      CASE WHEN a.suchvektor @@ to_tsquery('german',
        replace(suchbegriff, ' ', ' & '))
        THEN 10 ELSE 0 END
      +
      -- Trigramm-Ähnlichkeit
      COALESCE(similarity(a.titel, suchbegriff) * 5, 0)
      +
      -- Phonetik (Bonus für Namensähnlichkeit)
      CASE WHEN metaphon(a.titel) = metaphon(suchbegriff)
        THEN 3 ELSE 0 END
      +
      -- Kurze Editier-Distanz (max 2 Änderungen)
      CASE WHEN levenshtein(a.titel, suchbegriff) <= 2
        THEN 2 ELSE 0 END
    )::FLOAT8 AS score
  FROM artikel a
  WHERE
    a.suchvektor @@ to_tsquery('german',
      replace(suchbegriff, ' ', ' & '))
    OR a.titel % suchbegriff
    OR metaphon(a.titel) = metaphon(suchbegriff)
    OR levenshtein(a.titel, suchbegriff) <= 2
  ORDER BY score DESC
  LIMIT 10;
END;
$$ LANGUAGE plpgsql;

-- Aufruf mit Tippfehler: findet trotzdem "Autobahn"
SELECT * FROM suche_artikel('Autoban');

-- Aufruf mit phonetischer Variante: findet "Schmidt"
SELECT * FROM suche_artikel('Schmitt');

Eine solche Abfrage deckt Volltext-Treffer, Tippfehler, phonetische Varianten und entfernte Ähnlichkeiten gleichzeitig ab – ohne einen externen Dienst. Der Score-Wert lässt sich beliebig anpassen.

5. pgvector – Semantische Vektor-Suche

pgvector ist eine PostgreSQL-Extension, die Vektor-Ähnlichkeitssuche direkt in der Datenbank ermöglicht. Text, Bilder oder andere Daten werden über Machine-Learning-Modelle (z. B. OpenAI Embeddings, Sentence-Transformers) in numerische Vektoren (Embeddings) umgewandelt. pgvector speichert diese Vektoren als eigenen Datentyp (vector) und kann per ORDER BY über Distanzmetriken wie L2 distance, cosine distance oder inner product die ähnlichsten Einträge finden – unterstützt durch IVFFlat- oder HNSW-Indizes für performante ANN-Suche (Approximate Nearest Neighbor).

Im Gegensatz zu tsvector sucht pgvector nicht nach exakten Wörtern oder Lexemen, sondern nach semantischer Ähnlichkeit: „König" und „Monarch" liegen im Vektorraum nah beieinander, auch wenn sie keine gemeinsamen Wortstämme teilen. Das Verfahren eignet sich für Empfehlungssysteme, semantische Duplikatserkennung, Ähnlichkeitssuche in Produktkatalogen und Retrieval-Augmented Generation (RAG) in KI-Anwendungen.

Bewertung: pgvector macht PostgreSQL zu einem ernsthaften Kandidaten für semantische Suche, die früher nur dedizierten Vektor-Datenbanken vorbehalten war. Die Integration in die bestehende SQL-Umgebung und der Verzicht auf einen zusätzlichen Dienst sind große Vorteile. Allerdings ist die Performance bei sehr großen Vektorkollektionen (>10 Mio. Vektoren) und die Feature-Tiefe (kein hybrides Scoring, kein eingebautes Highlighting) nicht mit Elasticsearch 8.x oder OpenSearch 2.x vergleichbar, die Vektor-Suche nativ mit textuellen Queries kombinieren.

Elasticsearch / OpenSearch

Dedizierte Suchserver wie Elasticsearch oder die OpenSearch-Variante sind als eigenständige Cluster konzipiert.

mermaid
flowchart TB
  subgraph ES["Elasticsearch-Cluster"]
    n1["Node 1<br/><small>Shard A (Primär)</small>"]
    n2["Node 2<br/><small>Shard A (Replica)<br/>Shard B (Primär)</small>"]
    n3["Node 3<br/><small>Shard B (Replica)</small>"]
  end
  app["Applikation"] --> lb["Load Balancer"]
  lb --> n1
  lb --> n2
  lb --> n3

  subgraph PG["PostgreSQL (Single-Node)"]
    db["DB-Server<br/><small>Ein Index, kein Sharding</small>"]
  end
  app2["Applikation"] --> db

  style n1 fill:#39f,color:#fff
  style n2 fill:#39f,color:#fff
  style n3 fill:#39f,color:#fff
  style db fill:#6a6,color:#fff

Der Funktionsumfang geht weit über das hinaus, was PostgreSQL bietet:

// Index-Definition mit deutschem Analyzer
PUT /artikel
{
  "settings": {
    "analysis": {
      "analyzer": {
        "german_advanced": {
          "type": "german",
          "stopwords": "_german_"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "titel": {
        "type": "text",
        "analyzer": "german_advanced",
        "fields": {
          "keyword": { "type": "keyword" },
          "trigram": {
            "type": "text",
            "analyzer": "trigram"
          }
        }
      },
      "inhalt":   { "type": "text", "analyzer": "german_advanced" },
      "status":   { "type": "keyword" },
      "preis":    { "type": "float" },
      "tags":     { "type": "keyword" },
      "erstellt": { "type": "date" }
    }
  },
  "settings": {
    "analysis": {
      "analyzer": {
        "trigram": {
          "tokenizer": "ngram",
          "ngram": { "min_gram": 3, "max_gram": 3 }
        }
      }
    }
  }
}
// Komplexe Suche mit Highlighting, Filtern, Boosting und Aggregation
GET /artikel/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "titel": {
              "query": "Autobahn",
              "fuzziness": "AUTO",
              "operator": "and",
              "boost": 3.0
            }
          }
        }
      ],
      "filter": [
        { "term": { "status": "published" } },
        { "range": { "preis": { "lte": 100 } } }
      ],
      "should": [
        { "match": { "tags": "neu" } }
      ]
    }
  },
  "aggregations": {
    "preis_gruppen": {
      "range": {
        "field": "preis",
        "ranges": [
          { "to": 10 },
          { "from": 10, "to": 50 },
          { "from": 50 }
        ]
      }
    },
    "tags": {
      "terms": { "field": "tags", "size": 20 }
    }
  },
  "highlight": {
    "fields": {
      "titel": { "number_of_fragments": 0 },
      "inhalt": { "fragment_size": 150 }
    }
  },
  "suggest": {
    "did_you_mean": {
      "text": "Autoban",
      "term": { "field": "titel" }
    }
  }
}
// Antwort (Auszug)
{
  "hits": {
    "total": 42,
    "hits": [
      {
        "_score": 12.34,
        "_source": { "titel": "Auto fahren auf der Autobahn" },
        "highlight": {
          "titel": ["Auto fahren auf der <em>Autobahn</em>"]
        }
      }
    ]
  },
  "aggregations": {
    "preis_gruppen": {
      "buckets": [
        { "key": "*-10.0",   "doc_count": 12 },
        { "key": "10.0-50.0","doc_count": 24 },
        { "key": "50.0-*",   "doc_count": 6 }
      ]
    }
  },
  "suggest": {
    "did_you_mean": [
      { "text": "Autobahn", "score": 0.95 }
    ]
  }
}

Elasticsearch liefert mit einem JSON-Request Highlighting, Fuzziness, Filter, Boosting, Aggregationen und "Did you mean?" aus einer Hand. Die Antwort ist direkt konsumierbar – kein manuelles Ranking, kein Post-Processing im Anwendungscode.

mermaid
flowchart LR
  Query["Suchanfrage"] --> es["Elasticsearch<br/>koordinierender Node"]
  es --> n1["Node 1<br/>Shard A"]
  es --> n2["Node 2<br/>Shard B"]
  n1 --> merge["Ergebnis-Merge<br/>Sortierung & Scoring"]
  n2 --> merge
  merge --> agg["Aggregationen<br/>Facetten"]
  merge --> hl["Highlighting<br/>Snippets"]
  merge --> suggest["Suggestions<br/>Did you mean?"]
  agg --> response["JSON-Response"]
  hl --> response
  suggest --> response
  style es fill:#39f,color:#fff
  style response fill:#6a6,color:#fff

Entscheidungsmatrix

mermaid
flowchart TD
  Frage{"Welche Suchanforderungen<br/>hast du?"}
  Frage -->|"Nur Volltext + Tippfehler"| PG1["PostgreSQL<br/>tsvector + pg_trgm"]
  Frage -->|"+ Phonetik (Namenssuche)"| PG2["PostgreSQL<br/>+ fuzzystrmatch"]
  Frage -->|"Millionen Dokumente<br/>oder Facetten"| ES1["Elasticsearch/<br/>OpenSearch"]
  Frage -->|"Semantische<br/>Vektor-Suche"| ES2["Elasticsearch 8+<br/>oder pgvector"]

  PG1 --> Menge{"Datenmenge > 50 Mio<br/>oder horizontale<br/>Skalierung nötig?"}
  PG2 --> Menge
  Menge -->|nein| PG_OK["✅ PostgreSQL reicht"]
  Menge -->|ja| ES_Cluster["→ Elasticsearch Cluster"]

  ES1 --> ES_Cluster
  ES2 --> ES_Cluster
  ES_Cluster --> ES_OK["✅ Elasticsearch nötig"]

  style PG_OK fill:#6a6,color:#fff
  style ES_OK fill:#39f,color:#fff
  style ES_Cluster fill:#39f,color:#fff
KriteriumPostgreSQLElasticsearch / OpenSearch
Tippfehlertoleranz✅ pg_trgm, fuzzystrmatch✅ Fuzziness, Suggest
Volltextsuche✅ tsvector/tsquery✅ Multi-Field, Analyzer
Phonetische Suche✅ fuzzystrmatch✅ (via Plugin)
Teilwortsuche✅ pg_trgm (ILIKE)✅ N-Gram-Tokenizer
Skalierung (>50 Mio. Docs)⚠️ Vertikal✅ Horizontal (Sharding)
Facettierung / Aggregation❌ Umständlich mit GROUP BY✅ Nativ
Vektor-Suche (semantisch)✅ pgvector (IVFFlat/HNSW-Indizes)✅ Native kNN + hybrid Scoring (ab ES 8.x)
Highlighting❌ Self-made✅ Integriert
"Did you mean?"❌ Self-made✅ Term Suggest
Betriebskomplexität✅ Kein zusätzlicher Dienst❌ Cluster-Operationen
Latenz (Single-Request)✅ 2–10 ms (Index-Lookup)⚠️ 10–50 ms (Netzwerk)
Kosten✅ In PostgreSQL enthalten❌ Eigenes Hosting oder Cloud

Wann reicht PostgreSQL?

PostgreSQL mit tsvector, pg_trgm, fuzzystrmatch und optional pgvector ist die richtige Wahl, wenn:

  • Daten und Suche auf demselben Server liegen (kein Netzwerk-Overhead)
  • Bis zu mehreren Millionen Dokumenten durchsucht werden
  • Keine Facettierung oder Aggregationen benötigt werden
  • Das Team PostgreSQL bereits beherrscht und kein Elasticsearch-Wissen aufbauen möchte
  • Die Infrastruktur einfach bleiben soll

Ideal für: CMS-Suche, Blog-Suche, einfache Produktsuche, interne Verwaltungsoberflächen, API-Endpunkte mit "Suche"-Funktion.

Wann braucht es Elasticsearch?

Ein dedizierter Suchserver wird interessant, wenn:

  • Sehr große Datenmengen (Milliarden Dokumente) über mehrere Maschinen verteilt werden müssen
  • Komplexe Suchanalysen mit Aggregationen, Facetten und Echtzeit-Statistiken nötig sind
  • Semantische Suche mit hybridem Scoring (Vektor + Text) benötigt wird, das Elasticsearch nativ kann, pgvector aber nur mit Zusatzaufwand
  • Hochverfügbarkeit und Ausfallsicherheit für die Suchfunktion vertraglich zugesichert werden müssen
  • "Did you mean?"-Vorschläge und Autovervollständigung aus dem Suchverlauf abgeleitet werden

Ideal für: E-Commerce-Suche, Log-Analyse (ELK-Stack), DMS-Suche, Wissensdatenbanken.

Fazit

PostgreSQL ist für 80 % der Suchanwendungen vollkommen ausreichend – besonders in Webanwendungen mit überschaubaren Datenmengen. Die Kombination aus tsvector (Volltext), pg_trgm (Tippfehler, Teilwörter), fuzzystrmatch (Phonetik) und optional pgvector (semantische Vektor-Suche) deckt ein breites Spektrum ab, ohne dass ein zweites System betrieben werden muss.

Erst wenn horizontale Skalierung, komplexe Facetten, hybrides Vektor-Text-Scoring (kombinierte Gewichtung aus Embedding-Distanz und textuellem Match) oder "Did you mean?" ins Spiel kommen, wird Elasticsearch / OpenSearch zum unverzichtbaren Werkzeug. Für reine Vektor-Ähnlichkeitssuche ohne diese Zusatzanforderungen ist pgvector dagegen eine vollwertige Alternative.

Der beste Ansatz: Mit PostgreSQL starten, den Suchindex beobachten und erst migrieren, wenn die Anforderungen es wirklich erfordern. Die Umstellung von PostgreSQL auf Elasticsearch ist gut dokumentiert – der umgekehrte Weg (unnötige Komplexität wieder abbauen) ist deutlich schwieriger.


Hinweis: Die PostgreSQL-Beispiele wurden mit Version 16 getestet. pg_trgm und fuzzystrmatch sind in der contrib-Extension enthalten und müssen ggf. mit CREATE EXTENSION aktiviert werden. pgvector muss separat installiert werden (nicht in contrib). Elasticsearch und OpenSearch beziehen sich auf die Versionen 8.x bzw. 2.x.

PostgreSQLElasticsearchOpenSearchVolltextsuchepg_trgmtsvectorFuzzystrmatchTrigrammSuche
Teilen