Job Executor -- Search API
The Search API provides a unified search endpoint that can query across multiple entity types (jobs, steps, collections) with pagination, sorting, and column-level filtering.
Base URL: http://localhost:9000
Prefix: /search
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /search | Search entities with filters |
POST /search
Search across entity types with full-text search and column-level filters.
Query parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
type | string | all | Entity type to search. Values: all, job, step, collection. |
Request body (FilterRequest):
{
"page": 0,
"size": 10,
"sortBy": "updatedAt",
"sortOrder": "desc",
"searchText": "sales report",
"filters": {
"category": {
"operator": "and",
"constraints": [
{ "value": "reporting", "matchMode": "equals" }
]
},
"tags": {
"operator": "or",
"constraints": [
{ "value": "finance", "matchMode": "contains" },
{ "value": "sales", "matchMode": "contains" }
]
}
}
}
Response:
{
"status": "Success",
"message": "Search completed successfully",
"data": [
{
"id": "job-abc-123",
"type": "job",
"name": "Send Monthly Sales Report",
"description": "Generates the monthly sales report.",
"category": "reporting",
"tags": ["sales", "finance"],
"updatedAt": "2026-04-02T09:00:00Z"
}
],
"meta": {
"totalElements": 1,
"page": 0,
"size": 10
}
}
FilterRequest Structure
The FilterRequest object controls pagination, sorting, text search, and column-level filtering.
Top-level fields
| Field | Type | Default | Description |
|---|---|---|---|
page | integer | 0 | Zero-based page number. |
size | integer | 10 | Number of results per page. |
sortBy | string | id | Field to sort by. |
sortOrder | string | desc | Sort direction: asc or desc. |
searchText | string | null | Free-text search. Matched against the entity's name and description fields. |
filters | Map<String, FilterGroup> | null | Column-level filters. The map key is the field name to filter on. |
FilterGroup
Each entry in the filters map is a FilterGroup that defines how multiple constraints on the same field are combined.
| Field | Type | Description |
|---|---|---|
operator | string | How to combine constraints: and (all must match) or or (any must match). |
constraints | FilterConstraint[] | Array of filter conditions for this field. |
FilterConstraint
Each constraint defines a single filter condition.
| Field | Type | Description |
|---|---|---|
value | any | The value to match against. Type depends on the field. |
matchMode | string | How to compare the field value to the constraint value. |
Match Modes
| matchMode | Description | Example |
|---|---|---|
equals | Exact match. | { "value": "reporting", "matchMode": "equals" } |
notEquals | Not equal to. | { "value": "draft", "matchMode": "notEquals" } |
contains | Field contains the value (case-insensitive substring). | { "value": "sales", "matchMode": "contains" } |
notContains | Field does not contain the value. | { "value": "test", "matchMode": "notContains" } |
startsWith | Field starts with the value. | { "value": "Send", "matchMode": "startsWith" } |
endsWith | Field ends with the value. | { "value": "Report", "matchMode": "endsWith" } |
in | Field value is in the provided array. | { "value": ["reporting", "it-ops"], "matchMode": "in" } |
gt | Greater than (for numeric/date fields). | { "value": "2026-01-01", "matchMode": "gt" } |
lt | Less than. | { "value": 100, "matchMode": "lt" } |
gte | Greater than or equal. | { "value": 0, "matchMode": "gte" } |
lte | Less than or equal. | { "value": 1000, "matchMode": "lte" } |
between | Between two values (inclusive). | { "value": [10, 50], "matchMode": "between" } |
MongoDB Filtering
Under the hood, FilterRequest is translated into MongoDB query criteria using MongoFilteringUtil. Each FilterGroup becomes a MongoDB $and or $or clause, and each FilterConstraint becomes a MongoDB comparison operator:
| matchMode | MongoDB Operator |
|---|---|
equals | $eq |
notEquals | $ne |
contains | $regex (case-insensitive) |
startsWith | $regex: /^value/i |
in | $in |
gt | $gt |
lt | $lt |
between | $gte + $lte |
Examples
Filter jobs by category and status
{
"page": 0,
"size": 20,
"sortBy": "name",
"sortOrder": "asc",
"filters": {
"category": {
"operator": "or",
"constraints": [
{ "value": "reporting", "matchMode": "equals" },
{ "value": "it-operations", "matchMode": "equals" }
]
}
}
}
Free-text search with no column filters
{
"page": 0,
"size": 10,
"sortBy": "updatedAt",
"sortOrder": "desc",
"searchText": "monthly report"
}
Combine free-text search with column filters
{
"page": 0,
"size": 10,
"sortBy": "updatedAt",
"sortOrder": "desc",
"searchText": "backup",
"filters": {
"tags": {
"operator": "or",
"constraints": [
{ "value": "database", "matchMode": "contains" },
{ "value": "infrastructure", "matchMode": "contains" }
]
}
}
}
Per-Entity Search Endpoints
In addition to the unified /search endpoint, individual entity APIs also expose search:
| Endpoint | Description |
|---|---|
POST /jobs/search | Search jobs only (see Jobs API) |
POST /step/search | Search steps only (see Steps API) |
These use the same FilterRequest body structure.