Skip to content

Commit 74cdc67

Browse files
authored
Merge pull request #164 from neo4j/add-spatial-filters-to-the-filters-page
Add spatial filters to the filters page
2 parents acc02f5 + 8736138 commit 74cdc67

File tree

3 files changed

+121
-116
lines changed

3 files changed

+121
-116
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
.scala_dependencies
2424
.settings
2525
.shell_history
26+
.vscode/
2627
Thumbs.db
2728
\#*
2829
bin/teamcity/

modules/ROOT/pages/queries-aggregations/filtering.adoc

Lines changed: 114 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ All types can be tested for either equality.
1111
For non-equality, you *must* use the xref:/queries-aggregations/filtering.adoc#_combining_operators[`NOT`] logical operator.
1212
For example:
1313

14-
.Filtering all Users named John
14+
.Filtering all users named John
1515
[source, graphql, indent=0]
1616
----
1717
query {
@@ -37,7 +37,7 @@ These are the operators available for numeric (`Int`, `Float`, xref::/types/scal
3737

3838
Here is an example of how to use them:
3939

40-
.Filtering Users younger than 50 years old
40+
.Filtering users younger than 50 years old
4141
[source, graphql, indent=0]
4242
----
4343
query {
@@ -50,10 +50,66 @@ query {
5050
----
5151

5252
Spatial types use numerical filtering differently and they also have additional options.
53-
See xref::/types/spatial.adoc#_filtering[Spatial types filtering] for more information.
53+
See xref:filtering.adoc#_spatial_types[Spatial types] for more information.
5454

55-
These same operators are disabled by default in the case of String comparisons.
56-
To enable, explicitly add them in the features options:
55+
== Logical operators
56+
57+
All operators can be combined using the logical operators `AND`, `OR`, and `NOT`.
58+
They can also be standalone operators, which means that they can be used as such and not be appended to field names.
59+
60+
These operators 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.
61+
62+
For example, if you want to match all actors by the name of either "Keanu" or not belonging to the "Pantoliano" family, that played in "The Matrix" movie, here is how you can query that:
63+
64+
[source, graphql, indent=0]
65+
----
66+
query {
67+
actors(where: {
68+
AND: [
69+
{
70+
OR: [
71+
{ name_CONTAINS: "Keanu" },
72+
{ NOT: { name_ENDS_WITH: "Pantoliano" } }
73+
]
74+
},
75+
{
76+
movies_SOME: { title: "The Matrix" }
77+
}
78+
]}
79+
) {
80+
name
81+
movies {
82+
title
83+
}
84+
}
85+
}
86+
----
87+
88+
89+
== String comparison
90+
91+
The following case-sensitive comparison operators are only available for use on `String` and `ID` types:
92+
93+
* `_STARTS_WITH`
94+
* `_ENDS_WITH`
95+
* `_CONTAINS`
96+
97+
Here is an example of how to use them:
98+
99+
.Filtering users with name starting with "J"
100+
[source, graphql, indent=0]
101+
----
102+
query {
103+
users(where: { name_STARTS_WITH: "J" }) {
104+
id
105+
name
106+
}
107+
}
108+
----
109+
110+
Additionally, numerical operators can be used for String comparisons.
111+
They are disabled default.
112+
To enable them, add them in the `filters` features options for `String`:
57113

58114
[source, javascript, indent=0]
59115
----
@@ -85,28 +141,6 @@ const features = {
85141
const neoSchema = new Neo4jGraphQL({ features, typeDefs, driver });
86142
----
87143

88-
89-
== String comparison
90-
91-
The following case-sensitive comparison operators are only available for use on `String` and `ID` types:
92-
93-
* `_STARTS_WITH`
94-
* `_ENDS_WITH`
95-
* `_CONTAINS`
96-
97-
Here is an example of how to use them:
98-
99-
.Filtering Users with name starting with "J"
100-
[source, graphql, indent=0]
101-
----
102-
query {
103-
users(where: { name_STARTS_WITH: "J" }) {
104-
id
105-
name
106-
}
107-
}
108-
----
109-
110144
== RegEx matching
111145

112146
The filter `_MATCHES` is also available for comparison of `String` and `ID` types.
@@ -178,39 +212,67 @@ Conversely, the following operator is available on array fields, and accepts a s
178212

179213
These operators are available for all types apart from `Boolean`.
180214

181-
== Logical operators
215+
== Filtering spatial types
182216

183-
All operators can be combined using the logical operators `AND`, `OR`, and `NOT`.
184-
They can also be standalone operators, which means that they can be used as such and not be appended to field names.
217+
Both the `Point` and the `CartesianPoint` types use xref::queries-aggregations/filtering.adoc#_numerical_operators[numerical operators] and have an additional `_DISTANCE` filter.
218+
Here is a list of what each filter does for the two types:
185219

186-
These operators 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.
220+
* `_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.
221+
* `_LTE`: checks if a point is less than or equal to the distance in the `distance` field away (in meters) from the point specified by the `point` field.
222+
* `_DISTANCE`: checks if a point is the exact distance in the `distance` field away (in meters) from the point specified by the `point` field.
223+
* `_GT`: checks if a point is greater than the distance in the `distance` field away (in meters) from the point specified by the `point` field.
224+
* `_GTE`: checks if a point is greater than or equal to the distance in the `distance` field away (in meters) from the point specified by the `point` field.
187225

188-
For example, if you want to match all actors by the name of either "Keanu" or not belonging to the "Pantoliano" family, that played in "The Matrix" movie, here is how you can query that:
226+
For a `Point` type, all filters take the following type as an argument:
189227

190228
[source, graphql, indent=0]
191229
----
192-
query {
193-
actors(where: {
194-
AND: [
195-
{
196-
OR: [
197-
{ name_CONTAINS: "Keanu" },
198-
{ NOT: { name_ENDS_WITH: "Pantoliano" } }
199-
]
200-
},
201-
{
202-
movies_SOME: { title: "The Matrix" }
203-
}
204-
]}
205-
) {
230+
input PointDistance {
231+
point: Point!
232+
distance: Float!
233+
}
234+
----
235+
236+
In practice, you can construct queries like the following, which finds all users within a 5km (5000m) radius of a `Point`:
237+
238+
[source, graphql, indent=0]
239+
----
240+
query CloseByUsers($longitude: Float!, $latitude: Float!) {
241+
users(where: { location_LTE: { point: { longitude: $longitude, latitude: $latitude }, distance: 5000 } }) {
206242
name
207-
movies {
208-
title
243+
location {
244+
longitude
245+
latitude
209246
}
210247
}
211248
}
212249
----
213250

251+
Similarly, for a `CartesianPoint` type, all filters take the following type as an argument:
252+
253+
[source, graphql, indent=0]
254+
----
255+
input CartesianPointDistance {
256+
point: CartesianPoint!
257+
distance: Float!
258+
}
259+
----
260+
261+
The same query for a `CartesianPoint`:
262+
263+
[source, graphql, indent=0]
264+
----
265+
query CloseByUsers($x: Float!, $y: Float!) {
266+
users(where: { location_LTE: { point: { x: $x, y: $y }, distance: 5000 } }) {
267+
name
268+
location {
269+
x
270+
y
271+
}
272+
}
273+
}
274+
----
275+
214276
== Querying an interface
215277

216278
You can use the `typename_IN` filter to filter interfaces.
@@ -244,7 +306,7 @@ type Post {
244306
likes: [User!]! @relationship(type: "LIKES", direction: IN)
245307
}
246308
----
247-
=== In the case of `n..1` relationships
309+
=== `n..1` relationships
248310

249311
An `author` represents an `n..1` relationship on `Post`, where a given `Post` is authored by one, and only one, `author`.
250312
The available filters here will be `author`.
@@ -270,12 +332,12 @@ query {
270332
}
271333
----
272334

273-
=== In the case of `n..m` relationships
335+
=== `n..m` relationships
274336

275337
In the previous example, `posts` represents a `n..m` relationship on `User`, where a given `User` can have any number of `posts`.
276338
Here are some query examples:
277339

278-
.Find all Users where all of their posts contain search term: `"neo4j"`
340+
.Find all users where all of their posts contain search term: `"neo4j"`
279341
[source, graphql, indent=0]
280342
----
281343
query {
@@ -285,7 +347,7 @@ query {
285347
}
286348
----
287349

288-
.Find all Users where none of their posts contains search term: `"cypher"`
350+
.Find all users where none of their posts contains search term: `"cypher"`
289351
[source, graphql, indent=0]
290352
----
291353
query {

modules/ROOT/pages/types/spatial.adoc

Lines changed: 6 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ The use of either of these types in a GraphQL schema automatically introduces th
1414

1515
The `Point` type is used to describe the two https://neo4j.com/docs/cypher-manual/current/values-and-types/spatial/#spatial-values-crs-geographic[Geographic coordinate reference systems] supported by Neo4j.
1616

17-
In order to use it in your schema, you quite simply add a field with a type `Point` to any type or types in schema, like the following:
17+
In order to use it in your schema, add a field with a type `Point` to any other type(s) in your schema, like the following:
1818

1919
[source, graphql, indent=0]
2020
----
@@ -23,9 +23,9 @@ type TypeWithPoint {
2323
}
2424
----
2525

26-
Once this has been done, the `Point` type is automatically added to your schema, in addition to all of the input and output types you need to query and manipulate spatial types through your API.
26+
The `Point` type is automatically added to your schema, in addition to the input and output types that you need to query and manipulate spatial types through your API.
2727

28-
These are the automatically generated types and how to use them:
28+
See xref::queries-aggregations/filtering.adoc#_filtering_spatial_types[Filtering spatial types] for filter options.
2929

3030
==== Type definition
3131

@@ -84,48 +84,12 @@ mutation CreateUsers($name: String!, $longitude: Float!, $latitude: Float!) {
8484
}
8585
----
8686

87-
==== Filtering
88-
89-
Besides the xref::queries-aggregations/filtering.adoc#filtering-numerical-operators[Numerical operators], the `Point` type has an additional `_DISTANCE` filter.
90-
Here is a list of what each filter does:
91-
92-
* `_LT`: checks that the specified `Point` field is less than the `distance` away in meters from the `Point` being compared against.
93-
* `_LTE`: checks that the specified `Point` field is less than or equal to the `distance` away in meters from the `Point` being compared against.
94-
* `_DISTANCE`: checks that the specified `Point` field is the exact `distance` away in meters from the `Point` being compared against.
95-
* `_GTE`: checks that the specified `Point` field is greater than the `distance` away in meters from the `Point` being compared against.
96-
* `_GT`: checks that the specified `Point` field is greater than or equal to the `distance` away in meters from the `Point` being compared against.
97-
98-
All of the filters take the following type as an argument:
99-
100-
[source, graphql, indent=0]
101-
----
102-
input PointDistance {
103-
point: Point!
104-
distance: Float!
105-
}
106-
----
107-
108-
In practice, you can construct queries such as the following which can find all users within a 5km (5000m) radius of a `Point`:
109-
110-
[source, graphql, indent=0]
111-
----
112-
query CloseByUsers($longitude: Float!, $latitude: Float!) {
113-
users(where: { location_LTE: { point: { longitude: $longitude, latitude: $latitude }, distance: 5000 } }) {
114-
name
115-
location {
116-
longitude
117-
latitude
118-
}
119-
}
120-
}
121-
----
122-
12387
[[cartesian-point]]
12488
=== `CartesianPoint`
12589

12690
The `CartesianPoint` type is used to describe the two https://neo4j.com/docs/cypher-manual/current/values-and-types/spatial/#spatial-values-crs-cartesian[Cartesian coordinate reference systems] supported by Neo4j.
12791

128-
To use it in the schema, add a field with a type `CartesianPoint` to any type or types, such as in this example:
92+
To use it in your schema, add a field with a type `CartesianPoint` to any type(s), such as in this example:
12993

13094
[source, graphql, indent=0]
13195
----
@@ -134,9 +98,9 @@ type TypeWithCartesianPoint {
13498
}
13599
----
136100

137-
Once this has been done, the `CartesianPoint` type is automatically added to your schema, in addition to all of the input and output types you will need to query and manipulate spatial types through your API.
101+
The `CartesianPoint` type is automatically added to your schema, in addition to the input and output types that you need to query and manipulate spatial types through your API.
138102

139-
These are the automatically generated types and how to use them:
103+
See xref::queries-aggregations/filtering.adoc#_filtering_spatial_types[Filtering spatial types] for filter options.
140104

141105
==== Type definition
142106

@@ -162,25 +126,3 @@ input CartesianPointInput {
162126
z: Float
163127
}
164128
----
165-
166-
==== Filtering
167-
168-
Besides the xref::queries-aggregations/filtering.adoc#filtering-numerical-operators[Numerical operators], the `CartesianPoint` type has an additional `_DISTANCE` filter.
169-
170-
Here is a list of what each filter does:
171-
172-
* `_LT`: checks that the specified `Point` field is less than the `distance` away from the `CartesianPoint` being compared against, in the units used to specify the points.
173-
* `_LTE`: checks that the specified `Point` field is less than or equal to the `distance` away from the `CartesianPoint` being compared against, in the units used to specify the points.
174-
* `_DISTANCE`: checks that the specified `Point` field is the exact `distance` away from the `CartesianPoint` being compared against, in the units used to specify the points.
175-
* `_GTE`: checks that the specified `Point` field is greater than the `distance` away from the `CartesianPoint` being compared against, in the units used to specify the points.
176-
* `_GT`: checks that the specified `Point` field is greater than or equal to the `distance` away from the `CartesianPoint` being compared against, in the units used to specify the points.
177-
178-
All of the filters take the following type as an argument:
179-
180-
[source, graphql, indent=0]
181-
----
182-
input CartesianPointDistance {
183-
point: CartesianPoint!
184-
distance: Float!
185-
}
186-
----

0 commit comments

Comments
 (0)