7.11. 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.

7.11.1. Setting Query Hints

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

7.11.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.

7.11.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.

7.11.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.

7.11.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

7.11.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

7.11.4. Filter Compatibility

GeoMesa provides a limited compatibility mode, which allows for using a newer client version with an older distributed-runtime version, for back-ends that have a distributed installation. Currently this is limited to GeoMesa 1.3.7 and 2.3.x, with the flags 1.3 and 2.3, respectively. Only certain basic queries are supported, without advanced options.

Key Type GeoServer Conversion
QueryHints.FILTER_COMPAT String distributed install version
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.FILTER_COMPAT(), "1.3");
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.FILTER_COMPAT, "1.3")
...&viewparams=FILTER_COMPAT:1.3

7.11.5. 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 String index name or identifier
import org.locationtech.geomesa.index.conf.QueryHints;

query.getHints().put(QueryHints.QUERY_INDEX(), "z2");
// or:
query.getHints().put(QueryHints.QUERY_INDEX(), "z2:5:geom");
import org.locationtech.geomesa.index.conf.QueryHints

query.getHints.put(QueryHints.QUERY_INDEX, "z2")
// or:
query.getHints.put(QueryHints.QUERY_INDEX, "z2:5:geom")
...&viewparams=QUERY_INDEX:z2

For more details, see Query Planning.

7.11.6. Query Planning Type

As explained above, GeoMesa uses cost-based query planning to determine the best index for a given query. By default, heuristics are used to pick the index. This method is quite fast, but may not always account for unusual data distributions. If heuristic-based query planning is not working as desired, stat-based query planning can be used, based on data statistics gathered during ingestion. Stats uses cost-based planning; Index uses heuristic-based planning. Note that currently, statistics have only been implemented for the Accumulo and Redis data stores - for other stores, heuristic-based planning will always be used.

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 index or stats
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.