Queries

Each node defined in type definitions will have two Query fields generated for it:

  1. One for querying data

  2. One for aggregating data

The examples in this chapter will use the following type definitions:

type Post {
    id: ID! @id
    content: String!
    creator: User! @relationship(type: "HAS_POST", direction: IN, properties: "PostedAt")
    createdAt: DateTime!
}

type User {
    id: ID! @id
    name: String!
    posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT, properties: "PostedAt")
    friends: [User!]! @relationship(type: "FRIENDS_WITH", direction: OUT)
}

interface PostedAt {
    date: DateTime
}

For which the following Query fields will be generated:

type Query {
    posts(where: PostWhere, options: PostOptions): [Post!]!
    postsAggregate(where: PostWhere): PostAggregationSelection!

    users(where: UserWhere, options: UserOptions): [User!]!
    usersAggregate(where: UserWhere): UserAggregationSelection!
}

Query

Each field for querying data accepts two arguments:

Querying for all User nodes

The following Query will return all User nodes, returning their ID and name.

query {
    users {
        id
        name
    }
}

Query for user with name "Jane Smith" and their posts

The following Query will return all Users, returning the content which they have posted.

query {
    users(where: { name: "Jane Smith" }) {
        id
        name
        posts {
            content
        }
    }
}

Undirected Queries

All relationships are created with a direction from one node to another. By default, all queries follow the direction defined in the relationship, however, in some cases we may need to query for all related nodes, regardless of the direction of the relationship. This can be achieved with the argument directed: false.

For example, the following query:

query {
    users {
        name
        friends: friends(directed: false) {
            name
        }
    }
}

Will return all user friends, regardless on the direction of the relationship "FRIENDS_WITH".

Undirected relationships can also be used in the same fashion with connections:

query Query {
  users {
    friendsConnection(directed: false) {
      edges {
        node {
          name
        }
      }
    }
  }
}

Note that undirected relationships are only supported in queries.

The type definitions for a relationship may define a different behaviour, so the directed option may not be available in some cases.

Aggregate

Neo4j GraphQL supports aggregations on fields with type:

  1. ID- String

  2. String - String

  3. Int - Numerical

  4. Float - Numerical

  5. BigInt - Numerical

  6. DateTime

  7. Time

  8. LocalTime

  9. LocalDateTime

  10. Duration

Numerical Fields will expose the following aggregation selections:

  1. min

  2. max

  3. average

  4. sum

String fields will expose:

  1. shortest

  2. longest

The rest will only expose:

  1. min

  2. max

Aggregation queries accepts a where argument for filtering data.

Counting Using aggregation

The following Query will count all User nodes:

query {
    usersAggregate {
        count
    }
}

Counting User nodes where name starts with "J"

query {
    usersAggregate(where: { name_STARTS_WITH: "J" }) {
        count
    }
}

Querying for the longest User name

query {
    usersAggregate {
        name {
            longest
        }
    }
}

Querying for first Post date

query {
    postsAggregate {
        createdAt {
            min
        }
    }
}

Related nodes can also be aggregated within a query by accessing the aggregation fields in the node. In these fields, you can count, aggregate the nodes or edges fields.

The same selections and types as before are available in relationship aggregations.

Counting all posts per users

query {
    users {
        id
        postsAggregate {
            count
        }
    }
}

Finding longest post per user

By using the node field, related nodes properties can be aggregated.

query {
    users {
        name
        postsAggregate {
            node {
                content {
                  longest
                }
            }
        }
    }
}

Aggregate relationships

Relationship properties can be aggregated as well by using the edge field.

query {
    users {
        name
        postsAggregate {
            edge {
              date {
                max
              }
            }
        }
    }
}

Undirected aggregation queries

When performing an aggregation on related nodes, the query against the relationship can be defined as an undirected using the argument directed: false:

query {
    users {
        id
        postsAggregate(directed: false) {
            count
        }
    }
}