CodamAIDocs
Themafertig

Suchmuster mit LIKE: % und _

Wie die Platzhalter % und _ in einer LIKE-Suche wirken, warum CDMS kein % automatisch ergänzt, dass es kein Escaping gibt und wovon Groß- und Kleinschreibung abhängt.

Ausprägungen
exakter Wert ohne %beginnt mit (abc%)endet auf (%abc)enthält (%abc%)genau ein Zeichen (_)% oder _ als echtes ZeichenGroß-/Kleinschreibung je DatenbankLIKE ist der StandardoperatorLIKE auf Nicht-Text-Feld

Worum es geht

In einer Suche (POST /query) schreibst du Filter wie diesen:

{ "key": "name", "value": "Muster%", "param": "LIKE" }

LIKE vergleicht einen Text mit einem Suchmuster. Im Muster gibt es zwei Platzhalter:

Zeichensteht fürBeispieltrifft
%beliebig viele Zeichen, auch keinsMus%Mus, Muster, Muster GmbH
_genau ein ZeichenM_ierMaier, Meier, aber nicht Mayer

Nicht zu verwechseln mit den Wildcards + und * in der Feldauswahl: Die bestimmen, welche Felder zurückkommen. % und _ bestimmen, welche Zeilen gefunden werden.

Welches Muster trifft was?

Beispieldaten: fünf Kunden mit diesen Namen.

Fünf Muster gegen fünf Namen
Muster GmbHMustermannAlt-Muster AGmusterMeisterMuster (value)
neinneinneinje DBneinMuster – ohne Platzhalter: nur genau dieser Text
jajaneinje DBneinMuster% – beginnt mit „Muster“
neinneinneinje DBnein%Muster – endet auf „Muster“
jajajaje DBnein%Muster% – enthält „Muster“
neinneinneinneinjaM__ster – M, zwei beliebige Zeichen, dann „ster“

„je DB“ heißt: Ob muster (klein) von Muster (groß) getroffen wird, entscheidet die Datenbank, nicht CDMS. Mehr dazu weiter unten.

Was auf dem Weg passiert

  1. 1
    Benutzer→Client
    tippt „Muster“ in die Suchbox
  2. 2
    Client
    baut den Filter. Hier entscheidet sich, ob Muster, Muster% oder %Muster% verschickt wird
  3. 3
    Client→CDMS
    schickt { "key": "name", "value": "%Muster%", "param": "LIKE" }
  4. 4
    CDMS
    übersetzt den Filter 1:1 in name LIKE '%Muster%'. Kein Umschreiben, kein Ergänzen, kein Escaping
  5. 5
    CDMS→Datenbank
    führt die Abfrage aus, zusammen mit den Filtern, die immer mitlaufen
  6. 6
    Datenbank
    vergleicht nach ihren eigenen Regeln (Kollation), also auch mit oder ohne Groß-/Kleinschreibung
    Ergebnis: Treffer kommen als Liste zurück

Alle Ausprägungen

LIKE in allen Formen

Wann: Suchbox, in der der Text irgendwo vorkommen darf.

Der Client schickt %text%. Das ist die übliche Form für eine freie Suche.

Ergebnis: Findet „Muster GmbH“, „Mustermann“ und „Alt-Muster AG“.

Wann: Autovervollständigung, Nummernkreise, Präfixe.

Der Client schickt text%. Diese Form ist auf großen Tabellen meist deutlich schneller als „enthält“, weil die Datenbank einen Index nutzen kann.

Ergebnis: Findet „Muster GmbH“ und „Mustermann“.

Wann: Dateiendungen, Domains in E-Mail-Adressen.

Der Client schickt %text, z. B. %@codamic.com.

Ergebnis: Alle Werte mit genau diesem Ende.

Wann: Schreibvarianten mit fester Länge, z. B. Meier/Maier.

_ steht für genau ein Zeichen. M_ier trifft Maier und Meier, M__er alle fünfbuchstabigen Namen mit M am Anfang und er am Ende.

Ergebnis: Nur Werte mit genau der passenden Länge.

Wann: meistens aus Versehen.

Der Client schickt text ohne %. Das ist ein Gleichheitsvergleich, nur je nach Datenbank ohne Beachtung der Groß-/Kleinschreibung.

Ergebnis: Nur exakt „text“. Wer Gleichheit meint, nimmt besser EQ.

Wann: Der gesuchte Text enthält selbst ein % oder _, etwa 10% oder max_wert.

CDMS kennt kein Escaping. max_wert findet auch maxXwert, weil _ als Platzhalter gilt. Ein echtes % oder _ lässt sich mit LIKE nicht gezielt suchen.

Ergebnis: Zu viele Treffer. Ausweg: EQ für exakte Werte oder im Client nachfiltern.

Wann: Der Filter hat kein param.

LIKE ist der Standardoperator. { "key": "name", "value": "Muster" } ist also ein LIKE ohne Platzhalter, und damit ein exakter Vergleich.

Ergebnis: Gleiches Verhalten wie „ohne Platzhalter“.

Groß- und Kleinschreibung

CDMS selbst macht nichts mit der Schreibweise. Ob muster und Muster gleich sind, entscheidet die Kollation der Datenbankspalte:

MySQL 8 (Produktion)
Standardkollation utf8mb4_0900_ai_ci
  • Groß-/Kleinschreibung wird ignoriert
  • Akzente werden meist ignoriert: „Muller“ findet „Müller“
  • gilt, solange die Spalte nicht anders angelegt ist
H2 (Tests)
  • Groß-/Kleinschreibung zählt
  • ein Test kann also anders ausgehen als die Produktion

Wofür LIKE nicht gedacht ist

  • Nur für Textfelder. Für Zahlen, Datum, Ja/Nein und IDs gibt es EQ, IN, BEFORE, AFTER und die anderen Operatoren.
  • Keine regulären Ausdrücke. [A-Z], .* oder ^ haben keine Sonderbedeutung.
  • Keine Volltextsuche. Wer über mehrere Felder sucht, verbindet mehrere LIKE-Filter in einer ODER-Gruppe.
Suche über drei Felder
Anfrage
"query": {
  "type": "OR",
  "filter": [
    { "key": "name",           "value": "%muster%", "param": "LIKE" },
    { "key": "email",          "value": "%muster%", "param": "LIKE" },
    { "key": "customerNumber", "value": "%muster%", "param": "LIKE" }
  ]
}
Antwort
Findet jeden Kunden, bei dem „muster“ in Name,
E-Mail ODER Kundennummer vorkommt.
Quellen im Code und in der Wissensdatenbank
  • CDMS/cdms-persistence-database – DatabaseConditionBuilder, case LIKE
  • CDMS/cdms-commons – ListSearchFilter (param = LIKE als Standard)
Suchen