Queries
Defining queries
Data in Triplit is organized into collections, so to define a query you must first specify which collection you want to query.
For example, if you want to query the users
collection, you would write the following:
const query = client.query('users');
Selecting attributes
To specify which attributes you want to return, you can use the select
method. This method accepts a list of attribute names for the collection as arguments.
const query = client.query('users').select(['id', 'name', 'email', 'dob']);
Relationships are only partially supported in Triplit. Specifically you may filter data based on a relationship, however related data is not selectable. Full support for relationships is on the roadmap (opens in a new tab).
If the type you are selecting is a record, you may also select a specific attribute of the record by using dot notation. The result will be an object with just the selected keys.
const query = client
.query('users')
.select(['id', 'address.street', 'address.city']);
// {id: 'abc', address: {street: '123 Main St', city: 'New York'}}
If you do not call select on a query, all attributes are selected.
Filtering
To filter results based on conditions, you can use the where
method. This method accepts a list of clauses as arguments. A clause is a tuple that takes the form [attribute, operator, value]
.
For example the following query will return all registered users.
const query = client
.query('users')
.select(['id', 'name', 'email', 'dob'])
.where('is_registered', '=', true);
Clauses can be passed to where
as a single clause or an array of clauses:
.where('is_registered', '=', true)
.where(['is_registered', '=', true])
.where([['is_registered', '=', true]])
If multiple clauses are provided, all clauses are joined with a logical AND. However, you may use or
and and
methods within the clause array to specify how clauses should be logically grouped and joined.
For example the following query will return all registered users who are either an admin or an owner.
import { or } from '@triplit/client';
const query = client
.query('users')
.select(['id', 'name', 'email', 'dob'])
.where([
[
['is_registered', '=', true],
or([
['role', '=', 'admin'],
['role', '=', 'owner'],
]),
],
]);
You may use dot notation to filter by attirbutes of a record.
const query = client.query('users').where('address.city', '=', 'New York');
Operators
See the list of data types for more information on the operators that can be used in a where clause.
Order
To order the results of a query, you can use the order
method. This method accepts a list of order clauses as an argument. An order clause is a tuple that takes the form [attribute, direction]
. direction
can be either ASC
or DESC
. Clauses are applied in the order they are provided.
For example the following query will return all users ordered by their creation date in descending order.
const query = client
.query('users')
.select(['id', 'name', 'email', 'dob'])
.order('created_at', 'DESC');
Clauses can be passed to order
as a single clause or an array of clauses:
.order('created_at', 'DESC')
.order(['created_at', 'DESC'])
.order([['created_at', 'DESC']])
You may use dot notation to order by attirbutes of a record.
const query = client.query('users').order('address.city', 'ASC');
Limit
Many times you will want to limit the number of results returned by a query. To do this, you can use the limit
method.
For example, the following query will return the 10 most recently created users.
const query = client
.query('users')
.select(['id', 'name', 'email', 'dob'])
.order('created_at', 'DESC')
.limit(10);
As a convenience, Triplit also provides a method fetchOne to fetch just the first entity of a query result.
Variables
You may pass variables to a query by using the variables
method. Variables are passed in as strings with $
prepended to the variable name.
For example, you may define a query that queries for restaurants that are open by cuisine:
const baseQuery = client.query('restaurants').where([
['is_open', '=', true],
['cuisine', '=', '$cuisine'],
]);
const openItalianRestaurantsQuery = baseQuery.variables({ cuisine: 'italian' });
const openMexicanRestaurantsQuery = baseQuery.variables({ cuisine: 'mexican' });
This can help prevent writing the same query multiple times with different values.
Certain variables are used internally by Triplit to aid with authorization and other features. These include:
$SESSION_USER_ID
Sync state
Triplit's client storage is split into two areas - an outbox for unsynced updates and a cache for synced updates. Sometimes you may want to indicate that to a user that data has not yet been saved to the server. To do this, you can use the syncStatus
method. This method accepts a single sync state (pending
, confirmed
, all
) as an argument.
For example, a messaging app could use two queries to build message sent indicators. In React:
const allMessagesQuery = client.query('messages').order(['createdAt', 'ASC']);
const pendingMessagesQuery = client
.query('messages')
.select(['id'])
.syncStatus('pending');
function Messages() {
const { results: allMessages } = useQuery(client, allMessagesQuery);
const { results: pendingMessages } = useQuery(client, pendingMessagesQuery);
return (
<div>
{allMessages.entries().map(([id, message]) => (
<div>
<p>{message.text}</p>
<p>{pendingMessages.has(id) ? 'Sending...' : 'Sent'}</p>
</div>
))}
</div>
);
}
Entity id
Setting entityId
on your query will return exclusively the requested entity if it exists.
For example, the following query will return just the user with id abc
, if it exists.
const query = client.query('users').entityId('abc');
You may also pass a DB variable to entityId
.
const query = client.query('users').entityId('$userId');
As a convenience, Triplit also provides a method fetchById to fetch an entity by its id.