6.9. Query Properties

GeoMesa provides advanced query capabilities through GeoTools query hints. You can use these hints to control various aspects of query processing, or to trigger distributed analytic processing.

6.9.1. Setting Query Hints

Query hints can be set in two ways - programmatically or through GeoServer requests.

6.9.1.1. Programmatic Hints

To set a hint directly in a query:

import org.geotools.data.Query;

Query query = new Query("typeName");
query.getHints().put(key, value);

Note that query hint values must match the class type of the query hint. See below for available hints and their types.

6.9.1.2. GeoServer Hints

To set a hint through GeoServer, modify your query URL to use the viewparams request parameter:

...&viewparams=key1:value1;key2:value2;

Hint values will be converted into the appropriate types. See below for available hints and their accepted values.

6.9.1.3. Command-Line Tools

When exporting features through the GeoMesa command line tools, query hints can be set using the --hints parameter. Hints should be specified in the form key1=value1;key2=value2. Hints are converted to the appropriate type according to the conventions for GeoServer hints.

6.9.2. Loose Bounding Box

By default, GeoMesa uses a less precise filter for primary bounding box queries. This is faster, and in most cases will not change the results returned. However, certain use-cases require an exact result. This can be set at the data store configuration level, or overridden per query.

Key Type GeoServer Conversion
QueryHints.LOOSE_BBOX Boolean true or false
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.LOOSE_BBOX(), Boolean.FALSE);
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.LOOSE_BBOX, false)
...&viewparams=LOOSE_BBOX:false

6.9.3. Exact Counts

By default, GeoMesa uses an estimate for counts. In certain cases, users may require exact counts. This may be set through the system property geomesa.force.count or per query. Note, however, that exact counts are expensive to calculate.

Key Type GeoServer Conversion
QueryHints.EXACT_COUNT Boolean true or false
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.EXACT_COUNT(), Boolean.TRUE);
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.EXACT_COUNT, true)
...&viewparams=EXACT_COUNT:true

6.9.4. Query Index

GeoMesa may be able to use several different indices to satisfy a particular query. For example, a query with a spatial filter and an attribute filter could potentially use either the primary spatial index or the attribute index. GeoMesa uses cost-based query planning to pick the best index; however, the index can be overridden if desired.

Key Type GeoServer Conversion
QueryHints.QUERY_INDEX GeoMesaFeatureIndex index name, or name:version
import org.locationtech.geomesa.accumulo.index.z2.Z2Index$;
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.QUERY_INDEX(), Z2Index$.MODULE$);
import org.locationtech.geomesa.accumulo.index.z2.Z2Index
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.QUERY_INDEX, Z2Index)
...&viewparams=QUERY_INDEX:z2

For more details, see Query Planning.

6.9.5. Query Planning Type

As explained above, GeoMesa uses cost-based query planning to determine the best index for a given query. If cost-based query planning is not working as desired, the legacy heuristic-based query planning can be used as a fall-back. Stats uses cost-based planning; Index uses heuristic-based planning.

Query planning can also be controlled through the system property geomesa.query.cost.type. See Runtime Configuration for details. If both a query hint and a system property are set, the query hint will take precedence.

Key Type GeoServer Conversion
QueryHints.COST_EVALUATION CostEvaluation stats or index
import org.locationtech.geomesa.index.planning.QueryPlanner.CostEvaluation;
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.COST_EVALUATION(), CostEvaluation.Index());
import org.locationtech.geomesa.index.planning.QueryPlanner.CostEvaluation
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.COST_EVALUATION, CostEvaluation.Index)
...&viewparams=COST_EVALUATION:index

See Query Planning for more information on query planning strategies.