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 within_radius method to search for all documents containing spatial data that is located
    within the specified distance from the given center point.

# Define a spatail query on index 'Events_ByNameAndCoordinates'
employees_within_radius = list(
    session.query_index_type(Events_ByNameAndCoordinates, Event)
    # 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 'within_radius', pass the radius and the center points coordinates
        lambda criteria: criteria.within_radius(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)
# Define an index with a spatial field
class Events_ByNameAndCoordinates(AbstractIndexCreationTask):
    def __init__(self):
        super().__init__()
        # Call 'CreateSpatialField' to create a spatial index-field
        # Field 'coordinates' will be composed of lat & lng supplied from the document
        self.map = (
            "from e in docs.Events select new {"
            "    name = e.name,"
            "    coordinates = CreateSpatialField(e.latitude, e.longitude)"
            "}"
        )
        # Documents can be retrieved
        # by making a spatial query on the 'coordinates' index-field


class Event:
    def __init__(self, Id: str = None, name: str = None, latitude: float = None, longitude: float = None):
        self.Id = Id
        self.name = name
        self.latitude = latitude
        self.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 relates_to_shape 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'
employees_within_radius = list(
    session.query_index_type(EventsWithWKT_ByNameAndWKT, EventWithWKT)
    # Call 'spatial' method
    .spatial(
        # Pass the spatial index-field containing the spatial data,
        "WKT",
        # Set the geographical search criteria, call 'relates_to_shape'
        lambda criteria: criteria.relates_to_shape(
            # Specify the WKT string
            shape_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
                          ))""",
            # Specify the relation between the WKT shape and the documents spatial data
            relation=SpatialRelation.WITHIN,
        ),
    )
)
# The query returns all matching Event properties
# that are located within the specified polygon.
# Define an index with a spatial field
class EventsWithWKT_ByNameAndWKT(AbstractIndexCreationTask):
    def __init__(self):
        super().__init__()
        self.map = "from e in docs.Events select new {" "    name = e.name," "    WKT = CreateSpatialField(e.WKT)" "}"


class EventWithWKT:
    def __init__(self, Id: str = None, name: str = None, WKT: str = None):
        self.Id = Id
        self.name = name
        self.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 order_by_distance or order_by_distance_descending 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'
employees_sorted_by_distance = list(
    session.query_index_type(Events_ByNameAndCoordinates, Event)
    # Filter results by geographical criteria
    .spatial("coordinates", lambda criteria: criteria.within_radius(20, 47.623473, -122.3060097))
    # Sort results, call 'order_by_distance'
    .order_by_distance(
        # Pass the spatial index-field containing the spatial data
        "coordinates",
        # Sort the results by their distance from this point
        47.623473,
        -122.3060097,
    )
)
# 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(AbstractIndexCreationTask):
    def __init__(self):
        super().__init__()
        # Call 'CreateSpatialField' to create a spatial index-field
        # Field 'coordinates' will be composed of lat & lng supplied from the document
        self.map = (
            "from e in docs.Events select new {"
            "    name = e.name,"
            "    coordinates = CreateSpatialField(e.latitude, e.longitude)"
            "}"
        )
        # Documents can be retrieved
        # by making a spatial query on the 'coordinates' index-field


class Event:
    def __init__(self, Id: str = None, name: str = None, latitude: float = None, longitude: float = None):
        self.Id = Id
        self.name = name
        self.latitude = latitude
        self.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.