|
| 1 | +# GeoShape Fields Usage In RediSearch |
| 2 | + |
| 3 | +NRedisStack now supports GEOSHAPE field querying. |
| 4 | + |
| 5 | +Any object that serializes the [well-known text (WKT)](https://en.wikipedia.org/wiki/Well-known_text_representation_of_geometry) as a `string` can be used with NRedisStack. |
| 6 | + |
| 7 | +Using GeoShape fields in searches with the [NetTopologySuite](https://github.com/NetTopologySuite/NetTopologySuite) library. |
| 8 | + |
| 9 | +## Example |
| 10 | + |
| 11 | +### Modules Needed |
| 12 | + |
| 13 | +```c# |
| 14 | +using StackExchange.Redis; |
| 15 | +using NRedisStack.RedisStackCommands; |
| 16 | +using NRedisStack.Search; |
| 17 | +using NetTopologySuite.Geometries; |
| 18 | +using NetTopologySuite.IO; |
| 19 | +``` |
| 20 | + |
| 21 | +### Setup |
| 22 | + |
| 23 | +```csharp |
| 24 | +// Connect to the Redis server: |
| 25 | +var redis = ConnectionMultiplexer.Connect("localhost"); |
| 26 | +var db = redis.GetDatabase(); |
| 27 | +// Get a reference to the database and for search commands: |
| 28 | +var ft = db.FT(); |
| 29 | + |
| 30 | +// Create WTKReader and GeometryFactory objects: |
| 31 | +WKTReader reader = new WKTReader(); |
| 32 | +GeometryFactory factory = new GeometryFactory(); |
| 33 | + |
| 34 | +``` |
| 35 | + |
| 36 | +### Create the index |
| 37 | + |
| 38 | +```csharp |
| 39 | +ft.Create(index, new Schema().AddGeoShapeField("geom", GeoShapeField.CoordinateSystem.FLAT)); |
| 40 | +``` |
| 41 | + |
| 42 | +### Prepare the data |
| 43 | + |
| 44 | +```csharp |
| 45 | +Polygon small = factory.CreatePolygon(new Coordinate[]{new Coordinate(1, 1), |
| 46 | +new Coordinate(1, 100), new Coordinate(100, 100), new Coordinate(100, 1), new Coordinate(1, 1)}); |
| 47 | +db.HashSet("small", "geom", small.ToString()); |
| 48 | + |
| 49 | +Polygon large = factory.CreatePolygon(new Coordinate[]{new Coordinate(1, 1), |
| 50 | +new Coordinate(1, 200), new Coordinate(200, 200), new Coordinate(200, 1), new Coordinate(1, 1)}); |
| 51 | +db.HashSet("large", "geom", large.ToString()); |
| 52 | +``` |
| 53 | + |
| 54 | +## Polygon type |
| 55 | + |
| 56 | +### Querying within condition |
| 57 | + |
| 58 | +```csharp |
| 59 | +Polygon within = factory.CreatePolygon(new Coordinate[]{new Coordinate(0, 0), |
| 60 | +new Coordinate(0, 150), new Coordinate(150, 150), new Coordinate(150, 0), new Coordinate(0, 0)}); |
| 61 | + |
| 62 | +SearchResult res = ft.Search(index, new Query("@geom:[within $poly]") |
| 63 | + .AddParam("poly", within.ToString()) // Note serializing the argument to string |
| 64 | + .Dialect(3)); // DIALECT 3 is required for this query |
| 65 | +``` |
| 66 | + |
| 67 | +The search result from redis is: |
| 68 | + |
| 69 | +```bash |
| 70 | +1) (integer) 1 |
| 71 | +2) "small" |
| 72 | +3) 1) "geom" |
| 73 | + 2) "POLYGON ((1 1, 1 100, 100 100, 100 1, 1 1))" |
| 74 | +``` |
| 75 | + |
| 76 | +Use the reader to get the polygon: |
| 77 | + |
| 78 | +```csharp |
| 79 | +reader.Read(res.Documents[0]["geom"].ToString()); |
| 80 | +``` |
| 81 | + |
| 82 | +### Querying contains condition |
| 83 | + |
| 84 | +```csharp |
| 85 | +Polygon contains = factory.CreatePolygon(new Coordinate[]{new Coordinate(2, 2), |
| 86 | +new Coordinate(2, 50), new Coordinate(50, 50), new Coordinate(50, 2), new Coordinate(2, 2)}); |
| 87 | + |
| 88 | +res = ft.Search(index, new Query("@geom:[contains $poly]") |
| 89 | + .AddParam("poly", contains.ToString()) // Note serializing the argument to string |
| 90 | + .Dialect(3)); // DIALECT 3 is required for this query |
| 91 | +
|
| 92 | +``` |
| 93 | + |
| 94 | +Our search result: |
| 95 | + |
| 96 | +```bash |
| 97 | +1) (integer) 2 |
| 98 | +2) "small" |
| 99 | +3) 1) "geom" |
| 100 | + 2) "POLYGON ((1 1, 1 100, 100 100, 100 1, 1 1))" |
| 101 | +4) "large" |
| 102 | +5) 1) "geom" |
| 103 | + 2) "POLYGON ((1 1, 1 200, 200 200, 200 1, 1 1))" |
| 104 | +``` |
| 105 | + |
| 106 | +### Searching with Coordinates |
| 107 | + |
| 108 | +```csharp |
| 109 | +Point point = factory.CreatePoint(new Coordinate(10, 10)); |
| 110 | +db.HashSet("point", "geom", point.ToString()); |
| 111 | + |
| 112 | +res = ft.Search(index, new Query("@geom:[within $poly]") |
| 113 | + .AddParam("poly", within.ToString()) // Note serializing the argument to string |
| 114 | + .Dialect(3)); // DIALECT 3 is required for this query |
| 115 | +
|
| 116 | +``` |
| 117 | + |
| 118 | +Our search result: |
| 119 | + |
| 120 | +```bash |
| 121 | +1) (integer) 2 |
| 122 | +2) "small" |
| 123 | +3) 1) "geom" |
| 124 | + 2) "POLYGON ((1 1, 1 100, 100 100, 100 1, 1 1))" |
| 125 | +4) "point" |
| 126 | +5) 1) "geom" |
| 127 | + 2) "POINT (10 10)" |
| 128 | +``` |
0 commit comments