Skip to Page NavigationSkip to Page NavigationSkip to Content
Keystone 6 is now in General Availability!

GraphQL Queries - Filters

We recently improved our GraphQL API so it’s easier to program and reason about. If you were using it prior to August 17th 2021, read this guide for info on how to upgrade.

Keystone provides a powerful GraphQL API for querying the data in your system. At the core of this API are query filters. This guide will show you how to use filters to get data you need.

The filter references in this guide are based on the schema defined in the Task Manager example project.

Scalar Filters

If we want to find all the Tasks in our system, we can use the query tasks().

{
tasks {
id
label
}
}

In general we don't want to grab all the tasks at once, but we want to find a particular set of tasks which match a certain condition. In Keystone we can do this by passing a where argument to the tasks() query.

If we want to find all the tasks with a label equal to "Hello" we can write:

{
tasks(where: { label: { equals: "Hello" } }) {
id
label
}
}

Keystone provides a wide range of different filters. If we want to find all those tasks which don't have a label of "Hello" we can write:

{
tasks(where: { label: { not: { equals: "Hello" } } }) {
id
label
}
}

The text() field type also supports searching for sub-strings within a field:

{
tasks(where: { label: { contains: "He" } }) {
id
label
}
}

Different field types support different filters. The field finishBy: timestamp(), for example, lets you filter by tasks with a due date after a particular point in time:

{
tasks(where: { finishBy: { gt: "2022-01-01T00:00:00.000Z" } }) {
id
label
}
}

For a full list of the different filters provided by each field type, please check the Query Filter API.

For more complex queries, you can combine multiple filters, and only those items which match all conditions will be returned.

{
tasks(where: {
label: { contains: "He" },
finishBy: { gt: "2022-01-01T00:00:00.000Z" }
}) {
id
label
}
}

Combined Filters

For more advanced queries, you might need to explicitly combine different filters.

AND

The AND operater accepts a list of sub-filters, and will only return those items which match all of these conditions.

{
tasks(where: { AND: [
{ label: { contains: "H" } },
{ label: { contains: "ll" } }
] }) {
id
label
}
}

OR

The OR operater accepts a list of sub-filters, and will only return those items which match at least one of these conditions.

{
tasks(where: { OR: [
{ label: { contains: "H" } },
{ label: { contains: "ll" } }
] }) {
id
label
}
}

NOT

The NOT operater accepts a list of sub-filters, and will only return those items which don't match the conditions. You'll generally only pass a single filter to NOT rather than a list but if you do a pass a list, they're ANDed together.

{
tasks(where: { NOT: {
label: { contains: "H" }
} }) {
id
label
}
}

Relationship Filters

As well as filtering by scalar fields, you can also filter against relationship fields. Relationship filters will depend on whether you have many: true or many: false configured on the field.

One

If you have many: false configured on the relationship field, then you can find items based on a where filter using the fields from the related list.

For example, to find all the tasks where the task is assigned to a used named "Alice", we can run the following query.

{
tasks(where: { assignedTo: { name: { equals: "Alice" } } }) {
id
label
}
}

For example, to find any tasks that have no assigned user, we can run the following query.

{
tasks(where: { assignedTo: null }) {
id
label
}
}

Many

If you have many: true configured on the relationship field, then you can find items based on whether some, none, or every of the related items match a where filter using the fields from the related list.

For example, to find all the people which have some posts with the label "Hello", we can run the following query:

{
people(where: { tasks: { some: { label: { equals: "Hello" } } } }) {
id
name
}
}