The API uses
type for Database and app for Space. See Terminology.Install the Cricket template into your own workspace to run every example in the Entities section as-is.
Overview
The general shape of an entity query is:- select Fields
- filter Entities
- order Entities
| Parameter (required in bold) | Description |
|---|---|
query.q/from | Database name in format space/name, such as Cricket/Player or fibery/user. Note that the case matters. |
query.q/select | Array of primitive Fields, entity Field objects, objects with entity collection Fields subqueries and entity collection Field aggregates. |
query.q/where | Filter expression represented as an array. |
query.q/order-by | Array of sorting expressions — sorting by multiple Fields is supported. |
query.q/limit | How many Entities to return. Use a bounded value (e.g. 1000) and paginate to read large datasets — see Pagination. "q/no-limit" is supported but discouraged. In sub-queries, use 100; "q/no-limit" is allowed today but planned for deprecation. |
query.q/offset | How many Entities to skip — useful for pagination. |
params | Object of parameters for filter expressions in { "$param": value } format. |
Cricket/Player Database used as an example
| Field name | Field type |
|---|---|
fibery/id | fibery/uuid |
fibery/public-id | fibery/text |
Cricket/Name | fibery/text |
Cricket/Full Name | fibery/text |
Cricket/Born | fibery/date |
Cricket/Shirt Number | fibery/int |
Cricket/Height | fibery/decimal |
Cricket/Retired | fibery/bool |
Cricket/Batting Hand | single-select |
Cricket/Current Team | entity Field |
Cricket/Former Teams | entity collection Field |
Select Fields
In this example we demonstrate the select form known as “vector select”. It’s general form is:<field-name> is used for primitive fields (strings, numbers, booleans and the like). For example, to select id and name (both are text fields):
<field-name> won’t work for fields that point to other entities, because it’s not clear what to include as the value. So the query must specify which fields from the referenced entity to include, and that’s what the <vec-dereference> form does. Here, to add the id of the user in created-by, we add the {thisField: [targetFields] selector:
fibery/created-by points to at most one user. When we have a field that point to many entities, that is a collection field, we should have a way to filter them. The dereference form is not sufficient and the <vec-subselect> form must be used. The subselect expression is a full query of its own (a subquery). Here we add to each result also a collection of assignees, where for each assignee we select only one field, id:
Cricket/Player database and select:
- a primitive Field
Cricket/Full Nameof primitive typefibery/text - a single-select
Cricket/Batting Hand - a related entity
Cricket/Current Team - an entity collection Field
Cricket/Former Teams - an aggregate (the oldest former team year of foundation).
Select aggregates
select-func is a Lisp-style function callq/countq/sumq/avgq/minq/max
It doesn’t matter if a Field is populated manually or via a Formula/Lookup — the query stays exactly the same.
Select count
Count is the only aggregate which can be used on the top level:Filter Entities
Filters (where) go into the q/where clause of the query. The general form is inspired by Lisp: it’s a list where the first element is an operator and the remaining elements are the values to check using the operator:- a primitive Field (height)
- two primitive Fields (birth date and retirement status)
- a single-select (batting hand)
- an entity Field (current team)
- an entity collection Field (former teams)
$param instead.
Cricket/Player Database used as an example
| Field name | Field type |
|---|---|
Cricket/Height | fibery/decimal |
Cricket/Youth Career | fibery/date-range |
Cricket/Retired | fibery/bool |
Cricket/Batting Hand | single-select |
Cricket/Current Team | entity Field |
Cricket/Former Teams | entity collection Field |
| Field type | Operators |
|---|---|
| Number, Date | =, !=, <, <=, >, >=, q/null? |
| Text | q/equals-ignoring-case?, q/not-equals-ignoring-case?, q/contains, q/not-contains, q/starts-with-ignoring-case?, q/ends-with-ignoring-case?, q/null-or-empty? |
| Boolean / null check | ["=", ["q/null?", ["FieldPath"]], "$boolParam"] |
| Reference | q/in, q/not-in, q/count |
| Date-range start/end | ["q/start", ["FieldPath"]], ["q/end", ["FieldPath"]] |
| Location | ["q/address", ["FieldPath"]] — parses to string, then use text operators |
q/and and q/or take multiple filter clauses as operands:
Order Entities
[ [["fibery/creation-date"], "q/asc"], [["fibery/id"], "q/asc"] ]
Sorting by fibery/id guarantees that Entities order won’t change on different executions of the same query. It is also the basis of cursor pagination.
Cricket/Player Database used as an example
| Field name | Field type |
|---|---|
Cricket/Height | fibery/decimal |
Cricket/Current Team | entity Field |