XAP

Geospatial Index

Geospatial indexes can be defined by using the @SpaceSpatialIndex and @SpaceSpatialIndexes annotations.

Lets assume we have a class called GasStation that has a Point property that describes its location and we want to execute geospatial queries against this property:

public class GasStation {
    private Point location;

    @SpaceSpatialIndex
    public Point getLocation() {
        return location;
    }
    
    public void setLocation(Point location) {
        this.location = location;
    }
}

Here is a query that will trigger the usage of this index:

SQLQuery<GasStation> query = new SQLQuery<GasStation>(GasStation.class, "location spatial:within ?")
                .setParameter(1, ShapeFactory.circle(p, 4.5d));

When using the Geospatial Index feature, complex geographic features may require an increase in the com.gs.replication.replicaProgressTimeout parameter.

See Geospatial Queries for more information on how geospatial queries work.

Nested Index

An index can be defined on a nested property to improve performance of nested queries. Nested properties indexing uses an additional attribute - path(). This attribute represents the path of the property within the nested object.

In the example below, the Point is a property of the class Location which is a property of GasStation:

import org.openspaces.spatial.SpaceSpatialIndex;

import com.gigaspaces.annotation.pojo.SpaceClass;
import com.gigaspaces.annotation.pojo.SpaceId;

@SpaceClass
public class GasStation {

    private Long id;
    private Location location;
    ...

    @SpaceSpatialIndex(path = "point")
    public Location getLocation() {
        return location;
    }
}
 
 
import org.openspaces.spatial.shapes.Point;

public class Location {

    private String address;
    private Point point;
}
import org.openspaces.spatial.SpaceSpatialIndex;

import com.gigaspaces.annotation.pojo.SpaceClass;
import com.gigaspaces.annotation.pojo.SpaceId;

@SpaceClass
public class GasStation {

    private Long id;
    private Location location;
    ...

    @SpaceSpatialIndexes({ @SpaceSpatialIndex(path = "point"), @SpaceSpatialIndex(path = "circle")})
    public Location getLocation() {
        return location;
    }
}
 
 
import org.openspaces.spatial.shapes.Point;

public class Location {

    private String address;
    private Point  point;
    private Circle circle;
}

The following is an example of a query that triggers this index:

SQLQuery<GasStation> query = new SQLQuery<GasStation>(GasStation.class, "location.point spatial:within ?")
                .setParameter(1, ShapeFactory.circle(p, 4.5d));
        GasStation station = gigaSpace.read(query);

Combining Spatial and Standard Predicates

Suppose our GasStation class contains a price property as well, and we want to enhance our query and find nearby gas stations whose price is lower than a certain threshold. We can simply add the relevant predicate to the query's criteria:

public GasStation findNearbyGasStation(Point location, int radius, double maxPrice) {
    SQLQuery<GasStation> query = new SQLQuery(GasStation.class, "location spatial:within ? AND price < ?")
        .setParameter(1, ShapeFactory.circle(location, radius))
        .setParameter(2, maxPrice);
    return gigaSpace.read(query);
}

You should make an effort to choose the optimal index. For example, If both location and price are indexed, the index which appears first in the query is the one that will be used. This may significantly affect the performance of your query, so it's recommended to estimate which index is most efficient for each query and put it first.

PUClosed This is the unit of packaging and deployment in the GigaSpaces Data Grid, and is essentially the main GigaSpaces service. The Processing Unit (PU) itself is typically deployed onto the Service Grid. When a Processing Unit is deployed, a Processing Unit instance is the actual runtime entity. Example


				<?xml version="1.0" encoding="UTF-8"?>
				<beans xmlns="http://www.springframework.org/schema/beans"
					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
				xmlns:os-core="http://www.openspaces.org/schema/core"
					xsi:schemaLocation="Index of /schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd
					http://www.openspaces.org/schema/core http://www.openspaces.org/schema/core/openspaces-core.xsd">
				
				<bean id="propertiesConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
					<property name="properties">
						<props>
							<prop key="dataGridName">dataGrid</prop>
							<prop key="strategy">BBox</prop>
							<prop key="directoryType">RAMDirectory</prop>
							<prop key="spatialContext">Spatial4J</prop>
							<prop key="spatialContextGeo">true</prop>
						</props>
					</property>
				</bean>

				<bean id="luceneSpatialQueryExtensionProvider" class="org.openspaces.spatial.spi.LuceneSpatialQueryExtensionProvider">
					<constructor-arg name="customProperties">
						<props>
							<prop key="lucene.strategy">${strategy}</prop>
							<prop key="lucene.storage.directory-type">${directoryType}</prop>
							<prop key="context">${spatialContext}</prop>
							<prop key="context.geo">${spatialContextGeo}</prop>
						</props>
					</constructor-arg>
				</bean>
				<os-core:space id="space" url="/./${dataGridName}">
					<os-core:query-extension-provider ref="luceneSpatialQueryExtensionProvider"/>
				</os-core:space>
				</beans>