Client
`query`
`include`

include

If you have defined a relation in your schema using RelationById, RelationOne, or RelationMany, you can include those related entities in a query.

For example, the following schema defines a relation between users and messages

const schema = {
  users: S.Schema({
    id: S.Id(),
    name: S.Id(),
    email: S.String(),
  }),
  messages: S.Schema({
    id: S.Id(),
    text: S.String(),
    sender_id: S.String(),
    sender: S.RelationById('users', '$sender_id'),
  }),
};

By default, a query on messages will not include the sender as an attribute. To include the sender, use the include method in the query builder.

const query = client.query('messages').include('sender');
 
/*
{
  id: '1',
  text: 'hello world!',
  sender_id: 'bob',
  sender: { id: 'bob', name: 'Bob Jones', email: 'bob@triplit.com' },
};
*/

Including multiple relations

If a collection has multiple relations, you can select them by chaining multiple include calls.

const query = client.query('messages').include('sender').include('receiver');

Aliasing and extending relations

You can extend and alias relations with the include method. Given a schema with a relation from directors to films:

const schema = {
  films: S.Schema({
    id: S.Id(),
    title: S.Id(),
    rating: S.Number(),
    directorId: S.String(),
  }),
  directors: S.Schema({
    id: S.Id(),
    name: S.String(),
    allFilms: S.RelationMany('films', {
      where: [['directorId', '=', '$1.id']],
    }),
  }),
};

You can write an adhoc query that narrows down a director's films to just their top 3, building off the existing allFilms relation.

const query = client
  .query('directors')
  .include('bestFilms', (rel) =>
    rel('allFilms').order('rating', 'DESC').limit(3).build()
  )
  .build();
 
const result = await client.fetch(query);
 
// And the result will be fully typed
// {
//   id: string;
//   name: string;
//   bestFilms: Map<string, { id: string; title: string; rating: number; directorId: string }>;
// }

This is also useful for querying nested data. For example:

const query = client
  .query('directors')
  .include('allFilms', (rel) => rel('allFilms').include('actors').build())
  .build();
 
// {
//   id: string;
//   name: string;
//   allFilms: Map<string, { id: string; title: string; rating: number; directorId: string, actors: Map<string, { ... }> }>;
// }

The extending query can use any valid query builder method, such as order, limit, where, etc.