Filtering

This is the documentation of the GraphQL Library version 6. For the long-term support (LTS) version 5, refer to GraphQL Library version 5 LTS.

This page covers how to apply filters to subscriptions in the Neo4j GraphQL Library. Note, however, that:

  • Filtering can only be applied at the root of the subscription operation.

  • Aggregations are not supported on subscription types and there is currently no available method.

A subscription can be created to target the changes to a node (create/update/delete) or to a relationship (`create/`delete).

While the format slightly differs depending on whether the subscription targets a node or a relationship, providing a where argument allows for filtering on the events that are returned to the subscription.

Operators

When creating a subscription, a number of operators are available for different types in the where argument.

Equality operators

All types can be tested for either equality or non-equality. For the Boolean type, these are the only available comparison operators.

Numerical operators

The following comparison operators are available for numeric types (Int, Float, BigInt):

  • _LT

  • _LTE

  • _GTE

  • _GT

Filtering on Temporal types and Spatial types is not currently supported.

String comparison

The following case-sensitive comparison operators are only available for use on String and ID types:

  • _STARTS_WITH

  • _ENDS_WITH

  • _CONTAINS

Array comparison

The following operator is available on non-array fields, and accepts an array argument:

  • _IN

Conversely, the following operator is available on array fields, and accepts a single argument:

  • _INCLUDES

These operators are available for all types apart from Boolean.

AND/OR operators

Complex combinations of operators are possible using the AND/ OR operators. They accept as argument an array of items of the same format as the where argument.

Check Combining operators for an example.

Subscribing to node events

The where argument allows specifying filters on top-level properties of the targeted nodes. Only events matching these properties and type are returned to the subscription.

As an example, consider the following type definitions:

type Movie @node {
    title: String
    genre: String
    averageRating: Float
    releasedIn: Int
}

Now, here is how filtering can be applied when creating a subscription:

CREATE

To filter subscriptions to create operations for movies by their genre, here is how to do it:

subscription {
    movieCreated(where: { genre_EQ: "Drama" }) {
        createdMovie {
            title
        }
    }
}

This way, only newly created movies with the genre "Drama" trigger events to this subscription.

The where argument only filters by properties set at the moment of creation.

UPDATE

Here is how to filter subscription to update operations in movies with average rating bigger than 8:

subscription {
    movieUpdate(where: { averageRating_GT: 8 }) {
        updatedMovie {
            title
        }
    }
}

This way, you should only receive events triggered by movies with the average rating bigger than 8 when they are modified.

The where argument only filters properties that already existed before the update.

This is how these events may look like:

mutation {
    makeTheMatrix: createMovies(input: {title: "The Matrix", averageRating: 8.7}) {
        title
        averageRating
    },
    makeResurrections: createMovies(input: {title: "The Matrix Resurrections", averageRating: 5.7}) {
        title
        averageRating
    },
}

mutation {
    updateTheMatrix: updateMovie(
        where: { title_EQ: "The Matrix" }
        update: { averageRating: 7.9 }
    ) {
        title
    },
    updateResurrections: updateMovie(
        where: { title_EQ: "The Matrix Resurrections" }
        update: { averageRating: 8.9 }
    ) {
        title
    }
}

Therefore, given the previously described subscription, these GraphQL operations should only triggered for "The Matrix" movie.

DELETE

Here is how to filter subscription to delete operations in movies by their genre, using the NOT filter:

subscription {
    movieDeleted(where: { NOT: { genre_EQ: "Comedy" } }) {
        deletedMovie {
            title
        }
    }
}

This way, only deleted movies of all genres except for "Comedy" should trigger events to this subscription.

The where argument only filters properties that already existed before the deletion process.

Combining operators

All previously mentioned operators can be combined using the AND, OR, and NOT operators. They accept an array argument with items of the same format as the where argument, which means they can also be nested to form complex combinations.

As an example, consider a user who likes comedy movies, but not romantic comedies from early 2000, and who has the Matrix Trilogy as their favorite titles. They could subscribe to any updates that cover this particular set of interests as follows:

subscription {
    movieUpdated(where: {
        OR: [
            { title_CONTAINS: "Matrix" },
            { genre_EQ: "comedy" },
            { AND: [
                { NOT: { genre_EQ: "romantic comedy" } },
                { releasedIn_GT: 2000 },
                { releasedIn_LTE: 2005 }
            ] },
        ]
    }) {
        updatedMovie {
            title
        }
    }
}