Query a Spatial Index


  • Documents that contain spatial data can be queried by spatial queries that employ geographical criteria.
    You have two options:

    • Dynamic spatial query
      Either make a dynamic spatial query on a collection (see how to make a spatial query).
      An auto-index will be created by the server.

    • Spatial index query
      Or, index your documents' spatial data in a static-index (see indexing spatial data)
      and then make a spatial query on this index ( described in this article ).

  • A few examples of querying a spatial index are provided below.
    A spatial query performed on a static-index is similar to the dynamic spatial query.
    Find all spatial API methods listed here.

  • Examples in this page:


Search by radius

  • Query the spatial index:

  • Use the withinRadius method to search for all documents containing spatial data that is located
    within the specified distance from the given center point.

// Define a spatial query on index 'Events/ByNameAndCoordinates'
const employeesWithinRadius = await session
    .query({ indexName: "Events/ByNameAndCoordinates"})
     // Call 'spatial' method
    .spatial(
        /// Pass the spatial index-field containing the spatial data
        "coordinates",
        // Set the geographical area in which to search for matching documents
        // Call 'withinRadius', pass the radius and the center points coordinates  
        criteria => criteria.withinRadius(20, 47.623473, -122.3060097))
    .all();

// The query returns all matching Event entities
// that are located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).
// Define an index with a spatial field
class Events_ByNameAndCoordinates extends AbstractJavaScriptIndexCreationTask {
    constructor() {
        super();
        const { createSpatialField } = this.mapUtils();

        this.map('events', e => {
            return {
                name: e.Name,
                // Call 'createSpatialField' to create a spatial index-field
                // Field 'coordinates' will be composed of lat & lng supplied from the document
                coordinates: createSpatialField(
                    e.latitude,
                    e.longitude
                )
                
                // Documents can be retrieved
                // by making a spatial query on the 'coordinates' index-field
            };
        });
    }
}

class Event {
    constructor(id, name, latitude, longitude) {
        this.id = id;
        this.name = name;
        this.latitude = latitude
        this.longitude = longitude;
    }
}
from index "Events/ByNameAndCoordinates"
where spatial.within(
    Coordinates,
    spatial.circle(20, 47.623473, -122.3060097)
)

// The query returns all matching Event entities
// that are located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).

Search by shape

  • Query the spatial index:
    Use the relatesToShape method to search for all documents containing spatial data that is located
    in the specified relation to the given shape.

  • The shape in the query is specified as either a circle or a polygon in a WKT format.
    See polygon rules here.

  • The relation to the shape can be one of: Within, Contains, Disjoint, Intersects.

  • See more usage examples in the dynamic search by shape query.

// Define a spatial query on index 'EventsWithWKT/ByNameAndWKT'
const employeesWithinShape = await session
    .query({ indexName: "EventsWithWKT/ByNameAndWKT" })
     // Call 'spatial' method
    .spatial(
        // Pass the spatial index-field containing the spatial data
        "wkt",
        // Set the geographical search criteria, call 'relatesToShape'
        criteria => criteria.relatesToShape(
            // Specify the WKT string
            `POLYGON ((
                   -118.6527948 32.7114894,
                   -95.8040242 37.5929338,
                   -102.8344151 53.3349629,
                   -127.5286633 48.3485664,
                   -129.4620208 38.0786067,
                   -118.7406746 32.7853769,
                   -118.6527948 32.7114894
            ))`,
            // Specify the relation between the WKT shape and the documents spatial data
            "Within"
        ))
    .all();

// The query returns all matching Event entities
// that are located within the specified polygon.
// Define an index with a spatial field
class EventsWithWKT_ByNameAndWKT extends AbstractJavaScriptIndexCreationTask {
    constructor() {
        super();
        const { createSpatialField } = this.mapUtils();

        this.map('events', e => {
            return {
                name: e.Name,
                // Call 'createSpatialField' to create a spatial index-field
                // Field 'wkt' will be composed of the WKT string supplied from the document
                wkt: createSpatialField(e.wkt)

                // Documents can be retrieved by
                // making a spatial query on the 'wkt' index-field
            };
        });
    }
}

class EventWithWKT {
    constructor(id, name, wkt) {
        this.id = id;
        this.name = name;
        this.wkt = wkt;
    }
}
from index "EventsWithWKT/ByNameAndWKT"
where spatial.within(
    WKT,
    spatial.wkt("POLYGON ((
        -118.6527948 32.7114894,
        -95.8040242 37.5929338,
        -102.8344151 53.3349629,
        -127.5286633 48.3485664,
        -129.4620208 38.0786067,
        -118.7406746 32.7853769,
        -118.6527948 32.7114894))")
)

// The query returns all matching Event entities
// that are located within the specified polygon.
  • Note:
    The index in the above example indexes a WKT string in the spatial index-field.
    However, you can query by shape also on spatial data that is indexed as lat/lng coordinates.

Sort results

  • Query the spatial index:
    Use orderByDistance or orderByDistanceDescending to sort the results by distance from a given point.

  • By default, distance in RavenDB measured in kilometers.
    The distance can be rounded to a specific range.

// Define a spatial query on index 'Events_ByNameAndCoordinates'
const employeesSortedByDistance = await session
    .query({ indexName: "Events/ByNameAndCoordinates" })
     // Filter results by geographical criteria
    .spatial(
        "coordinates",
        criteria => criteria.withinRadius(20, 47.623473, -122.3060097))
     // Sort results, call 'orderByDistance'
    .orderByDistance(
        // Pass the spatial index-field containing the spatial data
        "coordinates",
        // Sort the results by their distance from this point: 
        47.623473, -122.3060097)
    .all();

// Return all matching Event entities located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).

// Sort the results by their distance from a specified point,
// the closest results will be listed first.
// Define an index with a spatial field
class Events_ByNameAndCoordinates extends AbstractJavaScriptIndexCreationTask {
    constructor() {
        super();
        const { createSpatialField } = this.mapUtils();

        this.map('events', e => {
            return {
                name: e.Name,
                // Call 'createSpatialField' to create a spatial index-field
                // Field 'coordinates' will be composed of lat & lng supplied from the document
                coordinates: createSpatialField(
                    e.latitude,
                    e.longitude
                )
                
                // Documents can be retrieved
                // by making a spatial query on the 'coordinates' index-field
            };
        });
    }
}

class Event {
    constructor(id, name, latitude, longitude) {
        this.id = id;
        this.name = name;
        this.latitude = latitude
        this.longitude = longitude;
    }
}
from index "Events/ByNameAndCoordinates"
where spatial.within(
    Coordinates,
    spatial.circle(20, 47.623473, -122.3060097)
)
order by spatial.distance(
    Coordinates,
    spatial.point(47.623473, -122.3060097)
)

// The query returns all matching Event entities located within 20 kilometers radius
// from point (47.623473 latitude, -122.3060097 longitude).

// Sort the results by their distance from a specified point,
// the closest results will be listed first.