Zum Inhalt springen

Suchen und Blättern

Kurzantwort: POST /query mit einem parameter-Block: query beschreibt den Filterbaum aus AND/OR-Gruppen, order die Sortierung, page und limit die Seite. Ohne limit bekommen Sie alle Treffer — setzen Sie es immer.


{
"response": ["id", "name", "status"],
"parameter": {
"meta": true,
"page": 0,
"limit": 25,
"order": [{ "field": "name", "order": "ASC" }],
"query": {
"type": "AND",
"filter": [
{ "key": "status", "value": "ACTIVE", "param": "EQ" },
{ "key": "name", "value": "Muster", "param": "LIKE" }
],
"group": []
}
}
}
FeldStandardBedeutung
metatrueGesamtzahl der Treffer mitliefern
page0Seite, nullbasiert
limit-1Seitengröße; -1 heißt unbegrenzt
orderSortierung, mehrere Kriterien möglich
queryFilterbaum
OperatorBedeutungBeispielwert
EQgleich"ACTIVE"
NEQungleich"ACTIVE"
LIKEenthält (Standard, wenn nichts angegeben ist)"Muster"
INin der Liste — kommasepariert in einem String"a,b,c"
ISNULL / ISNOTNULLleer / nicht leerWert wird ignoriert
BEFORE / SAMEORBEFOREDatum vor / vor oder gleich"2026-01-01"
AFTER / SAMEORAFTERDatum nach / nach oder gleich"2026-01-01"
MEMBEROFdie Sammlung des Objekts enthält dieses ElementID oder Wert

IN erwartet einen String, kein Array. "value": "a,b,c" ist richtig, "value": ["a","b","c"] nicht.

Jede Gruppe hat einen type (AND oder OR), eine Liste filter und eine Liste group für Untergruppen:

{
"type": "AND",
"filter": [{ "key": "status", "value": "ACTIVE", "param": "EQ" }],
"group": [
{
"type": "OR",
"filter": [
{ "key": "city", "value": "Berlin", "param": "EQ" },
{ "key": "city", "value": "Hamburg", "param": "EQ" }
]
}
]
}

Ergibt: status = ACTIVE AND (city = Berlin OR city = Hamburg).

type ist standardmäßig OR. Wer AND meint, muss es hinschreiben — ein vergessenes type ist die häufigste Ursache für „zu viele Treffer”.

Punktnotation läuft über Referenzen:

{ "key": "customer.address.city", "value": "Berlin", "param": "EQ" }

Objekte ohne diese Beziehung fallen dabei nicht heraus — der Server verknüpft mit einem Left Join.

Dasselbe gilt beim Sortieren:

"order": [
{ "field": "customer.name", "order": "ASC" },
{ "field": "createdOn", "order": "DESC" }
]

order kennt ASC, DESC und NONE.

parameter gilt immer für die Objekte, die die Abfrage selbst liefert. Wollen Sie eine referenzierte Liste einschränken — die Aufträge eines Kunden, die Positionen eines Auftrags —, gehört das in den response-Teil:

{
"response": [
"id", "name",
{
"field": "orders",
"response": ["id", "total", "status"],
"parameter": {
"limit": 5,
"page": 0,
"order": [{ "field": "total", "order": "DESC" }],
"query": {
"type": "AND",
"filter": [{ "key": "status", "value": "OPEN", "param": "EQ" }]
}
}
}
],
"parameter": {
"limit": 25,
"query": {
"type": "AND",
"filter": [{ "key": "city", "value": "Berlin", "param": "EQ" }]
}
}
}

Gelesen wird das so: 25 Kunden aus Berlin, und zu jedem die fünf höchsten offenen Aufträge.

Was Sie einschränken wollenWohin es gehört
die Treffer der Abfrage selbstparameter auf oberster Ebene
eine referenzierte Listeparameter innerhalb des response-Eintrags dieser Liste

Der Grund ist technisch: Der äußere parameter-Block beschreibt genau eine Ergebnismenge — die der Abfrage. Eine Referenzliste wird pro Treffer separat geladen, deshalb muss ihre Steuerung dort stehen, wo die Liste angefordert wird.

Vier Dinge, die dabei zählen:

  • Der Bezug zum Elternobjekt wird automatisch ergänzt. Sie filtern nur auf das, was Sie zusätzlich einschränken wollen — nie auf die Rückreferenz selbst.
  • Das gilt auf jeder Ebene. Auch eine Liste innerhalb einer Liste nimmt ihren eigenen parameter-Block.
  • Ohne limit multipliziert sich die Datenmenge. 25 Kunden mit je 500 Aufträgen sind 12.500 Objekte in einer Antwort. Setzen Sie in verschachtelten Listen erst recht ein Limit.
  • Es gibt keine Trefferzahl für verschachtelte Listen. meta.totalCount bezieht sich nur auf die äußere Abfrage; die Unterlisten liefern die Objekte, aber keine Zählung. Wer „5 von 42 Aufträgen” anzeigen will, braucht dafür eine eigene Abfrage auf das Auftragsmodell.

Mehr zur Struktur des response-Teils in Daten lesen.

"parameter": { "page": 0, "limit": 25, "meta": true }

Die Antwort trägt die Zahlen mit:

"meta": { "totalCount": 137, "currentPage": 0, "currentPageSize": 25, "currentLimit": 25 }

Seitenzahl im Client: Math.ceil(totalCount / limit).

Wenn Sie totalCount nicht brauchen, sparen Sie mit "meta": false eine zusätzliche Zählabfrage — spürbar bei großen Tabellen.

Volltextähnliche Suche über mehrere Felder

{
"type": "OR",
"filter": [
{ "key": "name", "value": "muster", "param": "LIKE" },
{ "key": "email", "value": "muster", "param": "LIKE" },
{ "key": "customerNumber", "value": "muster", "param": "LIKE" }
]
}

Zeitraum

{
"type": "AND",
"filter": [
{ "key": "createdOn", "value": "2026-01-01 00:00:00", "param": "SAMEORAFTER" },
{ "key": "createdOn", "value": "2026-01-31 23:59:59", "param": "SAMEORBEFORE" }
]
}

Datums- und Zeitwerte folgen den Formaten yyyy-MM-dd HH:mm:ss, yyyy-MM-dd und HH:mm:ss.

Mehrere IDs auf einmal

{ "key": "id", "value": "id-1,id-2,id-3", "param": "IN" }

Nur Objekte ohne Zuordnung

{ "key": "customer", "value": "", "param": "ISNULL" }

Kein Filter wird stillschweigend ignoriert — das ist Absicht, denn ein verschluckter Filter liefert zu viele Daten:

AntwortUrsache
400key oder Operator fehlt, ungültige UUID als Wert, ungültiger Sortierpfad
500Feldname existiert im Modell nicht

Prüfen Sie bei 500 zuerst die Schreibweise des Feldes — sie ist groß-/kleinschreibungsempfindlich.

Zusätzlich zu Ihrem Filter ergänzt der Server unsichtbar:

  • den Mandanten (über die Wahl der Datenbank),
  • bei benutzereigenen Modellen den Besitzer,
  • konfigurierte Attributfilter aus Ihrem Profil.

Sie können diese Einschränkungen nicht umgehen; sie erklären, warum dieselbe Abfrage bei zwei Benutzern unterschiedlich viele Treffer liefert. Details unter Suche und Filter.