Skip to content

POST /combined/

Executes a multi-stage pipeline query: JOIN → SELECT → AGGREGATE in a single request. Each stage is optional. Stages execute in order and feed their output into the next stage.


Request

Query Parameters:

Parameter Description
db_name Name of the database

Body:

Parameter Type Required Default Description
namespace string ❌* Namespace for non-join queries. Required if join is not provided
join object JOIN configuration (see /join/ docs). If omitted, loads namespace directly
select object SELECT/filter configuration (see /select/ docs)
aggregate object AGGREGATE configuration (see /aggregate/ docs)
convert_types bool true Auto-convert string values to int/float where possible

At least one of join, select, or aggregate must be provided.


Behavior

Execution order:

  1. JOIN — if provided, joins two namespaces into a combined dataset. Otherwise loads namespace directly.
  2. SELECT — if provided, applies WHERE filters, column projection, DISTINCT, ORDER BY, LIMIT, and OFFSET to the current dataset.
  3. AGGREGATE — if provided, applies pre-filters, GROUP BY, aggregations, HAVING, ORDER BY, and LIMIT to produce grouped results.

Each stage receives the output of the previous stage as its input, enabling complex pipelines in a single API call.


Responses

200 OK — rows result (no aggregate)

{
  "result_type": "rows",
  "total_rows": 5,
  "execution_time_ms": 31.2,
  "stages": [
    { "stage": "join",   "rows_output": 9,  "time_ms": 18.1 },
    { "stage": "select", "rows_output": 5,  "time_ms": 2.4  }
  ],
  "rows": [
    { "emp.name": "Alice", "emp.department": "Engineering", "ord.product": "Laptop", "ord.amount": 2500 }
  ]
}

200 OK — aggregated result

{
  "result_type": "aggregated",
  "total_groups": 3,
  "execution_time_ms": 42.7,
  "stages": [
    { "stage": "join",      "rows_output": 9, "time_ms": 18.1 },
    { "stage": "select",    "rows_output": 9, "time_ms": 1.2  },
    { "stage": "aggregate", "groups": 3,      "time_ms": 0.8  }
  ],
  "groups": [
    { "emp.department": "Engineering", "order_count": 4, "total_spend": 5270 }
  ]
}
Field Description
result_type "rows" or "aggregated"
stages Execution trace showing rows/groups and time per stage
rows Present when result_type is "rows"
groups Present when result_type is "aggregated"

Error Responses

Status Condition
400 No operations specified, or namespace missing when join not provided
404 Namespace not found
500 Unexpected internal error

Notes

  • The stages array in the response is useful for performance debugging — it shows exactly how many rows/groups each stage produced and how long it took.
  • convert_types is applied at the end for row results only. Aggregated results are always numeric.
  • ORDER BY in the SELECT stage uses stable sort — multiple ORDER BY fields are supported.

Example

import requests

SERVER_URL = "http://18.220.128.24:8000"
API_KEY    = "yourapitoken"

def combined(db_name: str, query: dict) -> dict:
    response = requests.post(
        f"{SERVER_URL}/combined/",
        headers={"X-API-Key": API_KEY},
        params={"db_name": db_name},
        json=query,
    )
    response.raise_for_status()
    return response.json()


# Join employees + orders, filter completed orders, aggregate spend by department
result = combined("my_db", {
    "join": {
        "left_namespace":  "employees",
        "right_namespace": "orders",
        "join_type":       "inner",
        "join_conditions": [{"left_field": "id", "right_field": "employee_id", "operator": "eq"}],
        "left_prefix":     "emp",
        "right_prefix":    "ord",
    },
    "select": {
        "where": [{"field": "ord.status", "operator": "eq", "value": "completed"}]
    },
    "aggregate": {
        "group_by": ["emp.department"],
        "aggregations": [
            {"field": "ord.order_id", "operation": "count", "alias": "order_count"},
            {"field": "ord.amount",   "operation": "sum",   "alias": "total_spend"},
        ],
        "order_by": ["-total_spend"],
    },
})
print(result)