Skip to content

Authorization and filtering #254

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 2, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions modules/ROOT/content-nav.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
** xref:types/interfaces.adoc[Interfaces]
** xref:types/unions.adoc[Union]
** xref:types/relationships.adoc[]
* xref:filtering.adoc[]
* xref:neo4jgraphql-class.adoc[]
* xref:directives/index.adoc[]
** xref:directives/database-mapping.adoc[]
Expand All @@ -35,11 +36,8 @@
* xref:queries-aggregations/index.adoc[Queries and aggregations]
** xref:queries-aggregations/queries.adoc[]
** xref:queries-aggregations/aggregations.adoc[]
** xref:queries-aggregations/filtering.adoc[]
** xref:queries-aggregations/sorting.adoc[]
** xref:queries-aggregations/pagination/index.adoc[]
*** xref:queries-aggregations/pagination/offset-based.adoc[]
*** xref:queries-aggregations/pagination/cursor-based.adoc[]
** xref:queries-aggregations/pagination.adoc[]

* xref:mutations/index.adoc[]
** xref:mutations/create.adoc[]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
[[filtering]]
= Filtering
:page-aliases: filtering.adoc
:page-aliases: queries-aggregations/filtering.adoc
:description: This page describes filtering operators.

You can apply filters when you query or aggregate data as well as use filtering rules for xref::/security/authorization.adoc#_filtering_rules[authorization].

When querying for data, a number of operators are available for the types in the `where` argument of a query or mutation, allowing you to filter query results or specify the set of objects a mutation applies to.

Operators can either be standalone operators (see xref:#_boolean_operators[]) or they are appended to field names (for example, xref:/queries-aggregations/filtering.adoc#_string_comparison[]).
Operators can either be standalone operators (see xref:#_boolean_operators[]) or they are appended to field names (for example, xref:#_string_comparison[]).

All operators can be combined using the Boolean operators `AND`, `OR`, and `NOT`.

Expand Down Expand Up @@ -42,7 +44,7 @@ query {
}
----

`name_CONTAINS` and `name_ENDS_WITH` are xref:/queries-aggregations/filtering.adoc#_string_comparison[String comparisons] while `movies_SOME` is a xref:/queries-aggregations/filtering.adoc#_relationship_filtering[relationship filter].
`name_CONTAINS` and `name_ENDS_WITH` are xref:#_string_comparison[String comparisons] while `movies_SOME` is a xref:#_relationship_filtering[relationship filter].

=== Equality operators

Expand All @@ -60,7 +62,7 @@ query {
}
----

For non-equality, you must use the xref:/queries-aggregations/filtering.adoc#_boolean_operators[`NOT`] logical operator.
For non-equality, you must use the xref:#_boolean_operators[`NOT`] logical operator.

.Filtering all users which are not named John
[source, graphql, indent=0]
Expand Down Expand Up @@ -101,11 +103,11 @@ query {
----

Spatial types use numerical filtering differently and they also have additional options.
See xref:filtering.adoc#_filtering_spatial_types[Filtering spatial types] for more information.
See xref:filtering.adoc#_spatial_type_filtering[] for more information.

==== Spatial type filtering

Both the `Point` and the `CartesianPoint` types use xref::queries-aggregations/filtering.adoc#_numerical_operators[numerical operators] and have an additional `_DISTANCE` filter.
Both the `Point` and the `CartesianPoint` types use xref:#_numerical_operators[numerical operators] and have an additional `_DISTANCE` filter.
Here is a list of what each filter does for the two types:

* `_LT`: checks if a point is less than the distance in the `distance` field away (in meters) from the point specified by the `point` field.
Expand Down
4 changes: 2 additions & 2 deletions modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ For every query and mutation that is executed against this generated schema, the
- xref::/types/index.adoc[Types], including temporal and spatial.
- Support for both node and relationship properties.
- Extensibility through the xref::/directives/custom-logic.adoc#_cypher[`@cypher` directive] and/or xref::/directives/custom-logic.adoc#_customresolver[Custom Resolvers].
- Extensive xref::queries-aggregations/filtering.adoc[Filtering] and xref::queries-aggregations/sorting.adoc[Sorting] options.
- Extensive xref::filtering.adoc[Filtering] and xref::queries-aggregations/sorting.adoc[Sorting] options.
- Options for xref::/directives/database-mapping.adoc[Database mapping] and value xref::/directives/autogeneration.adoc[Autogeneration].
- xref::/queries-aggregations/pagination/index.adoc[Pagination] options.
- xref::/queries-aggregations/pagination.adoc[Pagination] options.
- xref::/security/index.adoc[Security options] and additional xref::schema-configuration/index.adoc[Schema Configuration].
- An xref::ogm/index.adoc[OGM] (Object Graph Mapper) for programmatic interaction with your GraphQL API.
- A xref::getting-started/toolbox.adoc[Toolbox] (UI) to experiment with your Neo4j GraphQL API on Neo4j Desktop.
Expand Down
2 changes: 1 addition & 1 deletion modules/ROOT/pages/neo4jgraphql-class.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export type Neo4jFeaturesSettings = {

Use `Neo4jFiltersSettings` to enable numeric String comparisons and regular expression filters for Strings and IDs.
They are disabled by default.
See xref:queries-aggregations/filtering.adoc#_string_comparison[String comparison] and xref:queries-aggregations/filtering.adoc#_regex_matching[RegEx matching].
See xref:filtering.adoc#_string_comparison[String comparison] and xref:filtering.adoc#_regex_matching[RegEx matching].


=== `populatedBy` settings
Expand Down
12 changes: 6 additions & 6 deletions modules/ROOT/pages/ogm/reference.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ This method can be used to aggregate nodes, and maps to the underlying schema xr

|`where`
|`GraphQLWhereArg`
|A JavaScript object representation of the GraphQL `where` input type used for xref::queries-aggregations/filtering.adoc[Filtering].
|A JavaScript object representation of the GraphQL `where` input type used for xref::filtering.adoc[Filtering].
|===

==== Example
Expand Down Expand Up @@ -310,7 +310,7 @@ It returns a `Promise` which resolves to a `DeleteInfo` object:

|`where`
|`GraphQLWhereArg`
|A JavaScript object representation of the GraphQL `where` input type used for xref::queries-aggregations/filtering.adoc[Filtering].
|A JavaScript object representation of the GraphQL `where` input type used for xref::filtering.adoc[Filtering].

|`delete`
|`string` or `DocumentNode` or `SelectionSetNode`
Expand Down Expand Up @@ -350,11 +350,11 @@ It returns a `Promise` which resolves to an array of objects matching the type o

|`where`
|`GraphQLWhereArg`
|A JavaScript object representation of the GraphQL `where` input type used for xref::queries-aggregations/filtering.adoc[Filtering].
|A JavaScript object representation of the GraphQL `where` input type used for xref::filtering.adoc[Filtering].

|`options`
|`GraphQLOptionsArg`
|A JavaScript object representation of the GraphQL `options` input type used for xref::queries-aggregations/sorting.adoc[Sorting] and xref::/queries-aggregations/pagination/index.adoc[Pagination].
|A JavaScript object representation of the GraphQL `options` input type used for xref::queries-aggregations/sorting.adoc[Sorting] and xref::/queries-aggregations/pagination.adoc[Pagination].

|`selectionSet`
|`string` or `DocumentNode` or `SelectionSetNode`
Expand Down Expand Up @@ -408,7 +408,7 @@ It returns a `Promise` that resolves to the equivalent of the mutation response

|`where`
|`GraphQLWhereArg`
|A JavaScript object representation of the GraphQL `where` input type used for xref::queries-aggregations/filtering.adoc[Filtering].
|A JavaScript object representation of the GraphQL `where` input type used for xref::filtering.adoc[Filtering].

|`update`
|`any`
Expand All @@ -428,7 +428,7 @@ It returns a `Promise` that resolves to the equivalent of the mutation response

|`options`
|`GraphQLOptionsArg`
|A JavaScript object representation of the GraphQL `options` input type used for xref::queries-aggregations/sorting.adoc[Sorting] and xref::/queries-aggregations/pagination/index.adoc[Pagination].
|A JavaScript object representation of the GraphQL `options` input type used for xref::queries-aggregations/sorting.adoc[Sorting] and xref::/queries-aggregations/pagination.adoc[Pagination].

|`selectionSet`
|`string` or `DocumentNode` or `SelectionSetNode`
Expand Down
2 changes: 1 addition & 1 deletion modules/ROOT/pages/queries-aggregations/aggregations.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ query {

[NOTE]
====
The argument `where` can also be used in aggregation queries for xref::queries-aggregations/filtering.adoc[filtering] data.
The argument `where` can also be used in aggregation queries for xref::filtering.adoc[filtering] data.
====

== Aggregate related nodes
Expand Down
5 changes: 3 additions & 2 deletions modules/ROOT/pages/queries-aggregations/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This section addresses the following topics:

* xref:queries-aggregations/queries.adoc[Queries] - Read or fetch values.
* xref:queries-aggregations/aggregations.adoc[Aggregations] - Combine lists of types from different sources into a single list.
* xref:queries-aggregations/filtering.adoc[Filtering] - Filter query results to find objects.
* xref:queries-aggregations/sorting.adoc[Sorting] - Sort query results by individual fields.
* xref:queries-aggregations/pagination/index.adoc[Pagination] - Navigate result pages.
* xref:queries-aggregations/pagination.adoc[Pagination] - Navigate result pages.

Also, refer to xref:filtering.adoc[Filtering] for details on how to filter query results to find objects.
196 changes: 196 additions & 0 deletions modules/ROOT/pages/queries-aggregations/pagination.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
[[pagination]]
= Pagination
:page-aliases: pagination/index.adoc, pagination/offset-based.adoc, pagination/cursor-based.adoc, queries-aggregation/pagination/index.adoc, queries-aggregation/pagination/offset-based.adoc, queries-aggregation/pagination/cursor-based.adoc


The Neo4j GraphQL Library offers two mechanisms for pagination:

* Offset-based pagination - Pagination based on offsets, often associated with navigation via pages.
* Cursor-based pagination - Pagination based on cursors, often associated with infinitely-scrolling applications.


[[pagination-offset-based]]
== Offset-based pagination

Offset-based pagination, often associated with navigation via pages, can be achieved through the use of the `offset` and `limit` options available when querying for data.

Using the following type definition:

[source, graphql, indent=0]
----
type User {
name: String!
}
----

Fetch the first page of 10 by executing:

[source, graphql, indent=0]
----
query {
users(options: {
limit: 10
}) {
name
}
}
----

And then on subsequent calls, introduce the `offset` argument and increment it by 10 on each call.

Fetch the second page with:

[source, graphql, indent=0]
----
query {
users(options: {
offset: 10
limit: 10
}) {
name
}
}
----

Fetch the third page with:

[source, graphql, indent=0]
----
query {
users(options: {
offset: 20
limit: 10
}) {
name
}
}
----

And so on.


=== Total number of pages

You can fetch the total number of records for a certain type using its count query, and then divide that number by your entries per page in order to calculate the total number of pages.
This determines what the last page is, and whether there is a next page.

See xref::queries-aggregations/aggregations.adoc#_aggregate_related_nodes[count aggregation queries] for details on how to execute these queries.


=== Paginating relationship fields

Say that in addition to the `User` type above, there is also a `Post` type which a `User` has many of.
You can also fetch a `User` and then paginate through their posts:

[source, graphql, indent=0]
----
query {
users(where: {
name: "Billy"
}) {
name
posts(options: {
offset: 20
limit: 10
}) {
content
}
}
}
----


[[pagination-cursor-based]]
== Cursor-based pagination

On relationship fields, you are able to take advantage of cursor-based pagination, which is often associated with infinitely-scrolling applications.

Using the following type definition:

[source, graphql, indent=0]
----
type User {
name: String!
posts: [Post!]! @relationship(type: "HAS_POST", direction: OUT)
}

type Post {
content: String!
}
----

If you wanted to fetch the posts of user "John Smith" 10 at a time, you would first fetch 10:

[source, graphql, indent=0]
----
query {
users(where: { name: "John Smith" }) {
name
postsConnection(first: 10) {
edges {
node {
content
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
----

In the return value, if `hasNextPage` is `true`, you would pass `endCursor` into the next query of 10.
You can do this with a variable, for example, `$after` in the following query:

[source, graphql, indent=0]
----
query Users($after: String) {
users(where: { name: "John Smith" }) {
name
postsConnection(first: 10, after: $after) {
edges {
node {
content
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
}
----

You may continue until `hasNextPage` is `false` in the return - this is when you have reached the end of the data.


=== `totalCount`

The Connection fields also offer a `totalCount` field which can be used to calculate page numbers.
This is useful if you want to paginate by cursor but use page numbers in your application.

Add the `totalCount` field which returns the total number of results matching the filter used, for example:

[source, graphql, indent=0]
----
query Users($after: String) {
users(where: { name: "John Smith" }) {
name
postsConnection(first: 10) {
edges {
node {
content
}
}
pageInfo {
endCursor
hasNextPage
}
totalCount
}
}
}
----
Loading