Querying Relations
belongsTo
For asArray: false (belongsTo) relations, filter by the related record's columns using dot notation or nested notation. This translates to a LEFT JOIN. Chains of any depth are supported — see belongsTo → Multi-level chains for details.
// 1-level (either form works)
await app.service("todos").find({
query: { "user.name": "Alice" },
});
// Multi-level
await app.service("events").find({
query: { "assignment.customer.fullName": "Acme Corp" },
});hasMany
For asArray: true (hasMany) relations, you can filter parent records based on conditions on their children using $some, $none, and $every.
$some
Returns parent records where at least one related record matches the filter.
// Users who have at least one todo with text 'A-todo'
await app.service("users").find({
query: { todos: { $some: { text: "A-todo" } } },
});Translates to WHERE EXISTS (SELECT 1 FROM todos WHERE ...).
$none
Returns parent records where no related record matches the filter.
// Users who have no completed todos
await app.service("users").find({
query: { todos: { $none: { completed: true } } },
});Translates to WHERE NOT EXISTS (SELECT 1 FROM todos WHERE ...).
$every
Returns parent records where all related records match the filter.
// Users where every todo is completed
await app.service("users").find({
query: { todos: { $every: { completed: true } } },
});Implemented as "no child exists that does NOT match" — WHERE NOT EXISTS (SELECT 1 FROM todos WHERE NOT ...).
Combining with Other Queries
Relation operators can be combined with regular query filters:
// Active users who have at least one high-priority todo
await app.service("users").find({
query: {
active: true,
todos: { $some: { priority: "high" } },
},
});