Skip to content

Commit 32314a0

Browse files
Merge pull request #979 from redis/DOC-2761-geo-ref-page
DOC-2761 Geospatial reference information
2 parents 11d0f25 + 0d0a8b3 commit 32314a0

File tree

6 files changed

+384
-80
lines changed

6 files changed

+384
-80
lines changed

content/develop/data-types/geospatial.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ weight: 80
2020
Redis geospatial indexes let you store coordinates and search for them.
2121
This data structure is useful for finding nearby points within a given radius or bounding box.
2222

23+
{{< note >}}Take care not to confuse the Geospatial data type with the
24+
[Geospatial]({{< relref "/develop/interact/search-and-query/advanced-concepts/geo" >}})
25+
features in [Redis Query Engine]({{< relref "/develop/interact/search-and-query" >}}).
26+
Although there are some similarities between these two features, the data type is intended
27+
for simpler use cases and doesn't have the range of format options and queries
28+
available in Redis Query Engine.
29+
{{< /note >}}
30+
2331
## Basic commands
2432

2533
* [`GEOADD`]({{< relref "/commands/geoadd" >}}) adds a location to a given geospatial index (note that longitude comes before latitude with this command).
Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
---
2+
categories:
3+
- docs
4+
- develop
5+
- stack
6+
- oss
7+
- rs
8+
- rc
9+
- oss
10+
- kubernetes
11+
- clients
12+
description: Learn how to use geospatial fields and perform geospatial queries in Redis
13+
linkTitle: Geospatial
14+
math: true
15+
title: Geospatial
16+
weight: 14
17+
---
18+
19+
Redis Query Engine supports geospatial data. This feature
20+
lets you store geographical locations and geometric shapes
21+
in the fields of JSON objects.
22+
23+
{{< note >}}Take care not to confuse the geospatial indexing
24+
features in Redis Query Engine with the
25+
[Geospatial data type]({{< relref "/develop/data-types/geospatial" >}})
26+
that Redis also supports. Although there are some similarities between
27+
these two features, the data type is intended for simpler use
28+
cases and doesn't have the range of format options and queries
29+
available in Redis Query Engine.
30+
{{< /note >}}
31+
32+
You can index these fields and use queries to find the objects
33+
by their location or the relationship of their shape to other shapes.
34+
For example, if you add the locations of a set of shops, you can
35+
find all the shops within 5km of a user's position or determine
36+
which ones are within the boundary of a particular town.
37+
38+
Redis uses coordinate points to represent geospatial locations.
39+
You can store individual points but you can also
40+
use a set of points to define a polygon shape (the shape of a
41+
town, for example). You can query several types of interactions
42+
between points and shapes, such as whether a point lies within
43+
a shape or whether two shapes overlap.
44+
45+
Redis can interpret coordinates either as geographical longitude
46+
and latitude or as Cartesian coordinates on a flat plane.
47+
Geographical coordinates are ideal for large real-world locations
48+
and areas (such as towns and countries). Cartesian coordinates
49+
are more suitable for smaller areas (such as rooms in a building)
50+
or for games, simulations, and other artificial scenarios.
51+
52+
## Storing geospatial data
53+
54+
Redis supports two different
55+
[schema types]({{< relref "/develop/interact/search-and-query/basic-constructs/field-and-type-options" >}})
56+
for geospatial data:
57+
58+
- [`GEO`](#geo): This uses a simple format where individual geospatial
59+
points are specified as numeric longitude-latitude pairs.
60+
61+
- [`GEOSHAPE`](#geoshape): [Redis Community Edition]({{< relref "/operate/oss_and_stack" >}}) also
62+
supports `GEOSHAPE` indexing in v7.2 and later.
63+
This uses a subset of the
64+
[Well-Known Text (WKT)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry)
65+
format to specify both points and polygons using either geographical
66+
coordinates or Cartesian coordinates. A
67+
`GEOSHAPE` field supports more advanced queries than `GEO`,
68+
such as checking if one shape overlaps or contains another.
69+
70+
The sections below describe these schema types in more detail.
71+
72+
## `GEO`
73+
74+
A `GEO` index lets you represent geospatial data either as
75+
a string containing a longitude-latitude pair (for example,
76+
"-104.991531, 39.742043") or as a JSON array of these
77+
strings. Note that the longitude value comes first in the
78+
string.
79+
80+
For example, you could index the `location` fields of the
81+
the [JSON]({{< relref "/develop/data-types/json" >}}) objects
82+
shown below as `GEO`:
83+
84+
```json
85+
{
86+
"description": "Navy Blue Slippers",
87+
"price": 45.99,
88+
"city": "Denver",
89+
"location": "-104.991531, 39.742043"
90+
}
91+
92+
{
93+
"description": "Bright Red Boots",
94+
"price": 185.75,
95+
"city": "Various",
96+
"location": [
97+
"-104.991531, 39.742043",
98+
"-105.0618814,40.5150098"
99+
]
100+
}
101+
```
102+
103+
`GEO` fields allow only basic point and radius queries.
104+
For example, the query below finds products within a 100 mile radius of Colorado Springs
105+
(Longitude=-104.800644, Latitude=38.846127).
106+
107+
```bash
108+
FT.SEARCH productidx '@location:[-104.800644 38.846127 100 mi]'
109+
```
110+
111+
See [Geospatial queries]({{< relref "/develop/interact/search-and-query/query/geo-spatial" >}})
112+
for more information about the available query options and see
113+
[Geospatial indexing]({{< relref "/develop/interact/search-and-query/indexing/geoindex" >}})
114+
for examples of indexing `GEO` fields.
115+
116+
## `GEOSHAPE`
117+
118+
Fields indexed as `GEOSHAPE` support the `POINT` and `POLYGON` primitives from the
119+
[Well-Known Text](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry)
120+
representation of geometry. The `POINT` primitive defines a single point
121+
in a similar way to a `GEO` field.
122+
The `geom` field of the example JSON object shown below specifies a point
123+
(in Cartesian coordinates, using the standard x,y order):
124+
125+
```json
126+
{
127+
"name": "Purple Point",
128+
"geom": "POINT (2 2)"
129+
}
130+
```
131+
132+
The `POLYGON` primitive can approximate the outline of any shape using a
133+
sequence of points. Specify the coordinates of the corners in the order they
134+
occur around the shape (either clockwise or counter-clockwise) and ensure the
135+
shape is "closed" by making the final coordinate exactly the same as the first.
136+
137+
Note that `POLYGON` requires double parentheses around the coordinate list.
138+
This is because you can specify additional shapes as a comma-separated list
139+
that define "holes" within the enclosing polygon. The holes must have the opposite
140+
winding order to the outer polygon (so, if the outer polygon uses a clockwise winding
141+
order, the holes must use counter-clockwise).
142+
The `geom` field of the example JSON object shown below specifies a
143+
square using Cartesian coordinates in a clockwise winding order:
144+
145+
```json
146+
{
147+
"name": "Green Square",
148+
"geom": "POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))"
149+
}
150+
```
151+
152+
The following examples define one `POINT` and three `POLYGON` primitives,
153+
which are shown in the image below:
154+
155+
```
156+
POINT (2 2)
157+
POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))
158+
POLYGON ((2 2.5, 2 3.5, 3.5 3.5, 3.5 2.5, 2 2.5))
159+
POLYGON ((3.5 1, 3.75 2, 4 1, 3.5 1))
160+
```
161+
162+
{{< image filename="/images/dev/rqe/geoshapes.jpg" >}}
163+
164+
You can run various types of queries against a geospatial index. For
165+
example, the query below returns one primitive that lies within the boundary
166+
of the green square (from the example above) but omits the square itself:
167+
168+
```bash
169+
> FT.SEARCH geomidx "(-@name:(Green Square) @geom:[WITHIN $qshape])" PARAMS 2 qshape "POLYGON ((1 1, 1 3, 3 3, 3 1, 1 1))" RETURN 1 name DIALECT 4
170+
171+
1) (integer) 1
172+
2) "shape:4"
173+
3) 1) "name"
174+
2) "[\"Purple Point\"]"
175+
```
176+
177+
There are four query operations that you can use with `GEOSHAPE` fields:
178+
179+
- `WITHIN`: Find points or shapes that lie entirely within an
180+
enclosing shape that you specify in the query.
181+
- `CONTAINS`: Find shapes that completely contain the specified point
182+
or shape.
183+
- `INTERSECTS`: Find shapes whose boundary overlaps another specified
184+
shape.
185+
- `DISJOINT`: Find shapes whose boundary does not overlap another specified
186+
shape.
187+
188+
See
189+
[Geospatial queries]({{< relref "/develop/interact/search-and-query/query/geo-spatial" >}})
190+
for more information about these query types and see
191+
[Geospatial indexing]({{< relref "/develop/interact/search-and-query/indexing/geoindex" >}})
192+
for examples of indexing `GEOSHAPE` fields.
193+
194+
## Limitations of geographical coordinates
195+
196+
Planet Earth is actually shaped more like an
197+
[ellipsoid](https://en.wikipedia.org/wiki/Earth_ellipsoid) than a perfect sphere.
198+
The spherical coordinate system used by Redis Query Engine is a close
199+
approximation to the shape of the Earth but not exact. For most practical
200+
uses of geospatial queries, the approximation works very well, but you
201+
shouldn't rely on it if you need very precise location data (for example, to track
202+
the GPS locations of boats in an emergency response system).

content/develop/interact/search-and-query/basic-constructs/field-and-type-options.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ You can also use the following query syntax to perform more complex numeric quer
6666

6767
Geo fields are used to store geographical coordinates such as longitude and latitude. They enable geospatial radius queries, which allow you to implement location-based search functionality in your applications such as finding nearby restaurants, stores, or any other points of interest.
6868

69+
Redis Query Engine also supports [geoshape fields](#geoshape-fields) for more advanced
70+
geospatial queries. See the
71+
[Geospatial]({{< relref "/develop/interact/search-and-query/advanced-concepts/geo" >}})
72+
reference page for an introduction to the format and usage of both schema types.
73+
6974
You can add geo fields to the schema in [`FT.CREATE`]({{< baseurl >}}/commands/ft.create/) using this syntax:
7075

7176
```
@@ -82,6 +87,57 @@ You can query geo fields using the `@<field_name>:[<lon> <lat> <radius> <unit>]`
8287
FT.SEARCH cities "@coords:[2.34 48.86 1000 km]"
8388
```
8489

90+
See
91+
[Geospatial queries]({{< relref "/develop/interact/search-and-query/query/geo-spatial" >}})
92+
for more information and code examples.
93+
94+
## Geoshape fields
95+
96+
Geoshape fields provide more advanced functionality than [Geo](#geo-fields).
97+
You can use them to represent locations as points but also to define
98+
shapes and query the interactions between points and shapes (for example,
99+
to find all points that are contained within an enclosing shape). You can
100+
also choose between geographical coordinates (on the surface of a sphere)
101+
or standard Cartesian coordinates. Use geoshape fields for spatial queries
102+
such as finding all office locations in a specified region or finding
103+
all rooms in a building that fall within range of a wi-fi router.
104+
105+
See the
106+
[Geospatial]({{< relref "/develop/interact/search-and-query/advanced-concepts/geo" >}})
107+
reference page for an introduction to the format and usage of both the
108+
geoshape and geo schema types.
109+
110+
Add geoshape fields to the schema in
111+
[`FT.CREATE`]({{< baseurl >}}/commands/ft.create/) using the following syntax:
112+
113+
```
114+
FT.CREATE ... SCHEMA ... {field_name} GEOSHAPE [FLAT|SPHERICAL] [NOINDEX]
115+
```
116+
117+
Where:
118+
- `FLAT` indicates Cartesian (planar) coordinates.
119+
- `SPHERICAL` indicates spherical (geographical) coordinates. This is the
120+
default option if you don't specify one explicitly.
121+
- `NOINDEX` indicates that the field is not indexed. This is useful for storing
122+
coordinates that you don't want to search for, but that you still want to retrieve
123+
in search results.
124+
125+
Note that unlike geo fields, geoshape fields don't support the `SORTABLE` option.
126+
127+
Query geoshape fields using the syntax `@<field_name>:[<OPERATION> <shape>]`
128+
where `<operation>` is one of `WITHIN`, `CONTAINS`, `INTERSECTS`, or `DISJOINT`,
129+
and `<shape>` is the shape of interest, specified in the
130+
[Well-known text](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry)
131+
format. For example, the query below finds shapes that contain the point (2, 2):
132+
133+
```
134+
FT.SEARCH idx "(@geom:[CONTAINS $qshape])" PARAMS 2 qshape "POINT (2 2)" RETURN 1 name DIALECT 4
135+
```
136+
137+
See
138+
[Geospatial queries]({{< relref "/develop/interact/search-and-query/query/geo-spatial" >}})
139+
for more information and code examples.
140+
85141
## Vector fields
86142

87143
Vector fields are floating-point vectors that are typically generated by external machine learning models. These vectors represent unstructured data such as text, images, or other complex features. Redis Stack allows you to search for similar vectors using vector search algorithms like cosine similarity, Euclidean distance, and inner product. This enables you to build advanced search applications, recommendation systems, or content similarity analysis.

content/develop/interact/search-and-query/indexing/_index.md

Lines changed: 8 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -311,86 +311,14 @@ When JSONPath leads to multiple numerical values:
311311
- `null` values are skipped
312312
- Any other value type will cause an indexing failure
313313

314-
## Index JSON arrays as GEO
315-
316-
Starting with RediSearch v2.6.1, search can be done on an array of geo (geographical) values or on a JSONPath leading to multiple geo values.
317-
318-
Prior to RediSearch v2.6.1, only a single geo value was supported per GEO attribute. The geo value was specified using a comma delimited string in the form "longitude,latitude". For example, "15.447083,78.238306".
319-
320-
With RediSearch v2.6.1, a JSON array of such geo values is also supported.
321-
322-
In order to index multiple geo values, user either a JSONPath leading to a single array of geo values, or a JSONPath leading to multiple geo values, using JSONPath operators such as wildcard, filter, union, array slice, and/or recursive descent.
323-
324-
- `null` values are skipped
325-
- Other values will cause an indexing failure (bool, number, object, array, wrongly formatted GEO string, invalid coordinates)
326-
327-
For example, add to the item's list the `vendor_id`, that is, where an item can be physically purchased:
328-
329-
```sql
330-
127.0.0.1:6379> JSON.SET item:1 $ '{"name":"Noise-cancelling Bluetooth headphones","description":"Wireless Bluetooth headphones with noise-cancelling technology","connection":{"wireless":true,"type":"Bluetooth"},"price":99.98,"stock":25,"colors":["black","silver"], "max_level":[60, 70, 80, 90, 100], "vendor_id": [100,300]}'
331-
OK
332-
333-
127.0.0.1:6379> JSON.SET item:2 $ '{"name":"Wireless earbuds","description":"Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":64.99,"stock":17,"colors":["black","white"], "max_level":[80, 100, 120], "vendor_id": [100,200]}'
334-
OK
335-
336-
127.0.0.1:6379> JSON.SET item:3 $ '{"name":"True Wireless earbuds","description":"True Wireless Bluetooth in-ear headphones","connection":{"wireless":true,"type":"Bluetooth"},"price":74.99,"stock":20,"colors":["red","light blue"], "max_level":[90, 100, 110, 120], "vendor_id": [100]}'
337-
OK
338-
```
339-
340-
Now add some vendors with their geographic locations:
341-
342-
```sql
343-
127.0.0.1:6379> JSON.SET vendor:1 $ '{"id":100, "name":"Kwik-E-Mart", "location":["35.213,31.785", "35.178,31.768", "35.827,31.984"]}'
344-
OK
345-
346-
127.0.0.1:6379> JSON.SET vendor:2 $ '{"id":200, "name":"Cypress Creek", "location":["34.638,31.79", "34.639,31.793"]}'
347-
OK
348-
349-
127.0.0.1:6379> JSON.SET vendor:3 $ '{"id":300, "name":"Barneys", "location":["34.648,31.817", "34.638,31.806", "34.65,31.785"]}'
350-
OK
351-
```
352-
353-
To index the `vendor_id` numeric array, specify the JSONPath `$.vendor_id` in the `SCHEMA` definition during index creation:
354-
355-
356-
```sql
357-
127.0.0.1:6379> FT.CREATE itemIdx5 ON JSON PREFIX 1 item: SCHEMA $.vendor_id AS vid NUMERIC
358-
OK
359-
```
360-
361-
To index the `location` geo array, specify the JSONPath `$.location` in the `SCHEMA` definition during index creation:
362-
363-
364-
```sql
365-
127.0.0.1:6379> FT.CREATE vendorIdx ON JSON PREFIX 1 vendor: SCHEMA $.location AS loc GEO
366-
OK
367-
```
368-
369-
Now search for a vendor close to a specific location. For example, a customer is located at geo coordinates 34.5,31.5 and you want to get the vendors that are within the range of 40 km from our location:
370-
371-
```sql
372-
127.0.0.1:6379> FT.SEARCH vendorIdx '@loc:[34.5 31.5 40 km]' return 1 $.id
373-
1) (integer) 2
374-
2) "vendor:2"
375-
3) 1) "$.id"
376-
1) "200"
377-
4) "vendor:3"
378-
5) 1) "$.id"
379-
1) "300"
380-
```
381-
382-
Now look for products offered by these vendors:
383-
384-
```
385-
127.0.0.1:6379> FT.SEARCH itemIdx5 '@vid:[200 300]'
386-
1) (integer) 2
387-
2) "item:2"
388-
3) 1) "$"
389-
2) "{\"name\":\"Wireless earbuds\",\"description\":\"Wireless Bluetooth in-ear headphones\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":64.99,\"stock\":17,\"colors\":[\"black\",\"white\"],\"max_level\":[80,100,120],\"vendor_id\":[100,200]}"
390-
4) "item:1"
391-
5) 1) "$"
392-
2) "{\"name\":\"Noise-cancelling Bluetooth headphones\",\"description\":\"Wireless Bluetooth headphones with noise-cancelling technology\",\"connection\":{\"wireless\":true,\"type\":\"Bluetooth\"},\"price\":99.98,\"stock\":25,\"colors\":[\"black\",\"silver\"],\"max_level\":[60,70,80,90,100],\"vendor_id\":[100,300]}"
393-
```
314+
## Index JSON arrays as GEO and GEOSHAPE
315+
316+
You can use `GEO` and `GEOSHAPE` fields to store geospatial data,
317+
such as geographical locations and geometric shapes. See
318+
[Geospatial indexing]({{< relref "/develop/interact/search-and-query/indexing/geoindex" >}})
319+
to learn how to use these schema types and see the
320+
[Geospatial]({{< relref "/develop/interact/search-and-query/advanced-concepts/geo" >}})
321+
reference page for an introduction to their format and usage.
394322

395323
## Index JSON arrays as VECTOR
396324

0 commit comments

Comments
 (0)