see on GitHub

How to migrate Spatial from 3.x?

Spatial functionality have been merged into RQL and to reflect that change the Client API have integrated this feature into the session.Query and session.Advanced.DocumentQuery. Below migration samples will focus on the session.Query - the most common and recommended way of interaction with querying capabilities on RavenDB.

Namespaces

3.x 4.0
using Raven.Abstractions.Indexing;
using Raven.Client.Document;
using Raven.Client.Documents;
using Raven.Client.Documents.Indexes.Spatial;

Example I - Index

Following changes have been applied:

  1. All spatial fields must be created by using CreateSpatialField method
  2. No support for GeoJSON and other non-standard formats
  3. No support for spatial clustering
3.x
private class SpatialDoc_ByShapeAndPoint : AbstractIndexCreationTask<SpatialDoc>
{
    public SpatialDoc_ByShapeAndPoint()
    {
        Map = docs => from spatial in docs
            select new
            {
                Shape = spatial.Shape,
                Point = spatial.Point,
                _ = SpatialGenerate("Coordinates", spatial.Point.Latitude, spatial.Point.Longitude),
                _ = SpatialClustering("Clustering", spatial.Point.Latitude, spatial.Point.Longitude)
            };

        Spatial(x => x.Shape, options => options.Geography.Default());
        Spatial(x => x.Point, options => options.Cartesian.BoundingBoxIndex());
    }
}
4.0
private class SpatialDoc_ByShapeAndPoint : AbstractIndexCreationTask<SpatialDoc>
{
    public SpatialDoc_ByShapeAndPoint()
    {
        Map = docs => from spatial in docs
                      select new
                      {
                          Shape = CreateSpatialField(spatial.Shape.Wkt),
                          Point = CreateSpatialField(spatial.Point.Latitude, spatial.Point.Longitude),
                          Coordinates = CreateSpatialField(spatial.Point.Latitude, spatial.Point.Longitude)
                      };

        Spatial(x => x.Shape, options => options.Geography.Default());
        Spatial(x => x.Point, options => options.Cartesian.BoundingBoxIndex());
    }
}

Example II - RelatesToShape

3.x 4.0
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Customize(x => x
        .RelatesToShape(
            "Shape", 
            "Circle(32.1234 23.4321 d=10.0000)", 
            SpatialRelation.Within))
    .ToList();
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Spatial(
        x => x.Shape,
        criteria => criteria
            .RelatesToShape(
                "Circle(32.1234 23.4321 d=10.0000)",
                SpatialRelation.Within))
    .ToList();

Example III - WithinRadiusOf

3.x 4.0
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Customize(x => x
        .WithinRadiusOf("Shape", 10, 32.1234, 23.4321))
    .ToList();
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Spatial(
        x => x.Shape,
        criteria => criteria
            .WithinRadius(10, 32.1234, 23.4321))
    .ToList();

Example IV - SortByDistance

3.x 4.0
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Customize(x => x.SortByDistance())
    .Spatial(
        x => x.Shape, 
        criteria => criteria
            .WithinRadiusOf(10, 32.1234, 23.4321))
    .ToList();
List<SpatialDoc> results = session
    .Query<SpatialDoc, SpatialDoc_ByShapeAndPoint>()
    .Spatial(
        x => x.Shape,
        criteria => criteria
            .WithinRadius(10, 32.1234, 23.4321))
    .OrderByDistance(x => x.Shape, 32.1234, 23.4321)
    .ToList();

Remarks

Information

You can read more about Spatial in our dedicated Client API article or our Indexing article.