As of FiQueLa 3.0, the fluent helpers are expression-first:
select, where, having, groupBy, orderBy, and every scalar / aggregate helper accept full SQL expression strings. They route their field arguments through the same parser that powers FQL, so $query->select('ROUND(price * 1.21, 2) AS gross'), $query->groupBy('YEAR(date)'), $query->where('LOWER(name)', Op::EQ, 'alice'), and $query->sum('price + vat') all work end-to-end. Infix arithmetic (+ - * / %) and nested function calls are valid in every clause.Every query implements
\Stringable. Cast a query to a string to see the equivalent FQL representation — useful for debugging.Field path syntax
FiQueLa uses a dot-separated path to reference fields in nested data structures. Beyond simple dot access, the path syntax supports several advanced features:
Backtick escaping is useful when a key contains dots, spaces, or other special characters that would otherwise be interpreted as path separators.
select(), where(), orderBy(), groupBy(), on(), and inside function arguments. Scalar functions accept [] paths and operate on the flattened array — for example, $query->length('products.product[]') returns the element count, and $query->implode('products.product[].name', ', ') joins every nested name.
Prior to FiQueLa 3.0.2, scalar functions wrapping a
[] path returned null. Upgrade to 3.0.2 or later to use array-iterator paths inside scalar functions.Selecting fields
Useselect() to specify which fields to include. Dot notation accesses nested fields. Multiple select() calls merge their fields.
selectAll() to select all fields (equivalent to SELECT *). You can combine it with additional fields:
Aliases
Chainas() after select(), from(), or a join method to create an alias. The as() method is context-aware — it detects what was called before it and aliases accordingly:
When used after
select(), as() only aliases the last field in the preceding call. For example, select('id', 'name')->as('o') creates id, name AS o.DISTINCT
Remove duplicate rows withdistinct():
EXCLUDE
Useexclude() to remove fields from the output — useful when applying functions and you want only the computed result:
Aliased wildcards
When a source has an alias (fromfrom()->as() or a join), use alias.* in select() to select all fields from that specific source:
alias.* for both, a SelectException is thrown on ambiguous field conflicts.
Specifying the data path
Usefrom() to point to the data root within the file. Dot notation traverses nested structures:
Query\Provider::fromFileQuery(), the path embedded in the FileQuery string sets the initial from.
FROM aliasing
Chainas() after from() to alias the data source. Aliased fields are then accessible via alias.field dot notation:
FROM json(products.json).data.products AS p.
Pagination and limits
Sorting
ChainorderBy() with asc() or desc(). Multiple orderBy() calls define a multi-column sort. Dot notation is supported for sorting by nested fields.
Conditions
Filter rows withwhere(), then chain and(), or(), or xor():
Joins
Join other files or queries usinginnerJoin(), leftJoin(), rightJoin(), or fullJoin(), followed by on() to define the join condition. You can pass the alias as a second parameter or chain ->as() fluently:
Grouping and aggregations
Group rows withgroupBy() and apply aggregate functions:
Common table expressions (WITH)
Register a named subquery on the parent query withwith(). The CTE becomes visible to any JOIN or UNION branch composed on the parent.
with(string $name, Query $query), hasCte(string $name), getCte(string $name), getCtes().
See Common table expressions for full semantics, evaluation strategy, and limitations.
UNION
Combine results from multiple queries:SELECT * skip this check).
EXPLAIN
Inspect the query execution plan without running the full query, or run it with timing data:DESCRIBE
Usedescribe() to inspect the schema of a data source instead of querying its data. The result is a DescribeResult containing one row per column with type statistics, completeness, and uniqueness information.
DESCRIBE is mutually exclusive with SELECT, WHERE, GROUP BY, ORDER BY, LIMIT, JOIN, UNION, and EXPLAIN. Calling any of these after describe() throws a QueryLogicException.