In-Memory Indexing

The geomesa-memory module provides a in-memory cache of SimpleFeatures that supports indexing and filtering, using the CQEngine collection query engine. This is implemented by the GeoCQEngine class.

Index Configuration

When creating a GeoCQEngine, the attributes to index are passed in as a list of tuples in the form (name, type), where name corresponds to the attribute name, and type corresponds to the CQEngine index type:

Index Type

Attribute Types

Description

default

Any

Choose index type based on the attribute type being indexed

navigable

Date and numeric types

Supports equality, greater than and less than

radix

String

Supports string matching operations

unique

String, integer or long

Supports unique values. The presence of duplicate values will cause an exception

hash

String, integer or long

Supports equality

geometry

Geometries

Custom index for geometry types

If there is no appropriate index to use for a query, the whole data set will be searched.

Sample usage

import org.geotools.filter.text.ecql.ECQL
import org.locationtech.geomesa.memory.cqengine.GeoCQEngine
import org.locationtech.geomesa.memory.cqengine.utils.CQIndexType
import org.locationtech.geomesa.utils.geotools.SimpleFeatureTypes

// setup
val spec = "Who:String,*Where:Point:srid=4326"
val sft = SimpleFeatureTypes.createType("test", spec)

def buildFeature(sft: SimpleFeatureType, fid: Int): SimpleFeature = ???

// create a new cache
val cq = new GeoCQEngine(sft, Seq(("Who", CQIndexType.DEFAULT), ("Where", CQIndexType.GEOMETRY)))

// add a collection of features
cq.insert(Seq.tabulate(1000)(i => buildFeature(sft, i)))

// add a single feature
val feature = buildFeature(sft, 1001)
cq.insert(feature)

// remove a single feature
cq.remove(feature.getID)

// get an iterator with all features that match a filter
val filter = ECQL.toFilter("Who = 'foo' AND BBOX(Where, 0, 0, 180, 90)")
val reader = cq.query(filter)

// clear the cache
cq.clear()

You can also choose the geometry index type. By default a Bucket index is used that provides better performance in case of frequent inserts or updates. In the case of you need to search inside a immutable (or with few variation) collection of data you can use the QuadTree or the SRTtree index. To do that you must create the GeoCqEngine as in the following:

val cq1 = new GeoCQEngine(featureType, Seq(("Who", CQIndexType.DEFAULT), ("Where", CQIndexType.GEOMETRY)),geoIndexType = GeoIndexType.STRtree,geoIndexParam = Option.apply(new STRtreeIndexParam(/*nodeCapacity*/10)))
val cq2 = new GeoCQEngine(featureType, Seq(("Who", CQIndexType.DEFAULT), ("Where", CQIndexType.GEOMETRY)),geoIndexType = GeoIndexType.QuadTree)