What are table feature queries?
To access features in a table, you need to use the feature service query
operation. To do so, you can use ArcGIS Maps SDKs, open source libraries, scripting APIs, or the REST API to make a SQL query to a feature service. To make the request, you will need the service URL or item ID.
You use table features queries to:
- Access a subset of features in a table
- Request features with a SQL WhereClause query
- Return features in different data formats e.g. JSON, GeoJSON, and PBF
- Return all or a subset of attribute fields for features
- Return features without geometries
How to query table features
The steps to access and query features are:
- Find the service URL for the feature layer to query.
- Define the
query
SQL parameters (where clause). - Define the output parameters (data format).
- Execute the
query
.
Types of queries
In general, the two types of feature queries you can implement are repeatable queries and unique queries.
Repeatable query
A repeatable query is a query you send to a feature service that contains consistent and repeatable input values that multiple users will execute from an application. The values of the parameters such as geometry, SQL where clause, search text, spatial relationship operator, or a combination of them will all be the same for each request. Since the query is repeatable, the responses will be the same for the queries, and you can use cache
to ask the service to cache the results.
Below is an example of a repeatable query with a repeatable where clause:
https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0/query?f=pbf&cacheHint=true&resultRecordCount=100&where=UseType = 'Irrigated Farm'&outFields=APN,UseType,TaxRateCity,TaxRateArea,Roll_LandValue&returnGeometry=false&token=<ACCESS_TOKEN>
Unique query
A unique query is a query you send to a feature service that contains unique input values defined by the user of an application. The values of the parameters for the geometry, SQL where clause, search text, spatial relationship operator, or a combination of them are unique and unknown. Since the queries are unique, the responses are also unique and are not automatically cached. You should not use cache
to ask the service to cache results from unique queries.
Below is an example of a unique query with a user-defined geometry:
https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0/query?f=pbf&geometry={"rings":[[[-13228576.521843342,4033084.7250306536],[-13222485.595442941,4033084.7250306536],[-13222485.595442941,4030103.75557307],[-13228576.521843342,4030103.75557307],[-13228576.521843342,4033084.7250306536]]]}&outFields=APN,UseType,TaxRateCity,Roll_LandValue&spatialRel=esriSpatialRelIntersects&geometryType=esriGeometryPolygon&token=<ACCESS_TOKEN>
Feature queries and caches
When you query and/or display features, different response caches are available to help maximize the performance and scalability of applications. A response cache is the data returned from a query
request that is stored and managed so it can be reused by clients. Response caches are only beneficial to applications that make repeatable queries. Making use of response caches improves both performance and scalability allowing your application to perform well even when experiencing high load.
There are multiple levels of caches available to applications. This includes the following:
- Client-side cache: A response cache stored and managed by a web browser, native application, or operating system.
- CDN cache: A response cache stored and managed by CDN servers worldwide (ArcGIS Platform and ArcGIS Online only). This cache is configurable.
- Feature tile cache: A response cache stored and managed internally by the feature service.
All three levels of caches can exist at the same time. How the caches are used by an application, however, depends on the type of API you are using, the CDN cache max age settings you apply, and the parameters you include with the request.
In general, when a query
request is sent to a feature service, the response caches are accessed in the following order:
- Client-side cache (if available)
- CDN cache (if available)
- Feature tile cache (if available)
If a cache is available, the response cache is sent back to the client immediately. If a cache isn't available, the request will look for the next level of cache that is available. If no caches are found, the query is processed by the feature service and the response is sent back to the client. If the response is cacheable, it will be stored at the appropriate caching level so it can be reused in the future.
Client-side cache
A client-side cache is the response data from queries to the feature service stored in a web browser, native application, or operating system. If the cache is available, the applications use this cache first before making requests to the feature service. When using the cache, the ArcGIS Maps SDKs also check to see if the features have been updated in the feature service so it can update the local cache. A client-side cache is only used by individual applications and cannot be shared with others. When available, these are the highest-performing caches.
CDN cache
A CDN cache is the response data from queries stored on CDN servers around the world. The CDN caches the data returned from the service for requests for a length of time (cache
) that you specify in the hosted feature layer (item) settings. The CDN cache is for feature layers with the sharing level set to Everyone (public) for ArcGIS Online and Owner (private) for ArcGIS Platform. The CDN cache is shared and can be accessed by any application that can access the service. The CDN cache is used when the client-side cache is not available. If available, these are the next highest-performing caches.
CDN caches are only available when using ArcGIS Platform (private layers) or ArcGIS Online (public layers).
Feature tile cache
A feature tile is a data structure that contains the results of a query
request stored in the server. A feature tile is created when a query request contains result
or cache
. The tiles can be sent directly back to the client to satisfy a query request or stored in a feature tile cache, CDN cache, or client-cache for future use.
A feature tile cache is the response data from queries
stored at the service level as one or more feature tiles. A feature service cache is used when a client application sends consistent and repeatable queries to a feature service and the service stores the results as feature tiles for future use. The ArcGIS Maps SDKs use this mechanism to ask the feature service to store query responses as feature tiles on the service so they can be used by others. The cache is managed by the feature service and automatically updated if the underlying features are edited or updated. Feature service caches are shared and available to all client applications that send the same query request. Feature tile caches are used when client-side and CDN caches are not available.
Feature tile caches are available when using ArcGIS Platform, ArcGIS Online, or ArcGIS Enterprise (object store must be configured).
URL request
https://{host}/{organizationID}/ArcGIS/rest/services/{serviceName}/FeatureServer/{id}/query?{queryParameters}
https://{host}/{organizationID}/ArcGIS/rest/services/{serviceName}/FeatureServer/{id}/query?{queryParameters}
https://{host}/{webadaptor}/rest/services/Hosted/{serviceName}/FeatureServer/{id}/query?{queryParameters}
Required parameters
Name | Description | Examples |
---|---|---|
f | The format of the data returned. | f=json f=pjson f=geojson f=pbf f=html |
token | An API key or OAuth 2.0 access token. Learn how to get an access token in Security and authentication. | token=< |
SQL parameters
Use this parameter to define a WhereClause for a SQL query.
Name | Description | Examples |
---|---|---|
where | A SQL clause that defines which data to return based upon attribute values. To query based upon geometry, see the geometry and spatial parameters. Learn more about the SQL-92 format here. |
Output parameters
Use these parameters to define and optimize the query response.
Name | Description | Examples |
---|---|---|
out | A list of field names that specifies the attributes to return with any records (for example, out ). The more fields you request, the larger the attributes portion of the response JSON payload and the longer it could take to download. Only request the fields you need for display or analysis. To return all fields, which can be useful during development and testing, use out . | |
order | Order the records that are included in the response by specifying which fields to sort by and a sort order for each field: - ASC - ascending order (default)- DESC - descendingFor example, order . |
Cache parameters
Name | Description | Examples |
---|---|---|
cache | Ask the service to store the query response for later use. This should only be used when client applications send consistent and repeatable queries. Using cache can significantly improve performance. See the Query a feature layer (SQL) example. | cache cache |
Code examples
Query all features
To query and display features (records) in a table, you reference the layer by its URL or ID and specify which data attributes to return. In this example, a Trailheads hosted table is accessed and all of the records are displayed. To specify the fields returned, out
is used in the query.
Steps
- Get the hosted table URL and layer ID.
- Add the hosted table and define the fields.
- Display the fields and records.
const q = trailsLayer.createQuery()
q.where = "1=1"
q.cacheHint = true
q.outFields = Object.keys(outFields)
trailsLayer.queryFeatures(q).then(loadTable)
SQL query for features
To search for features (records) in a table, you can query features using a SQL where
clause. In the example below, a where
clause is used to return parcel features from a table based on input values. Since these queries are unknown and unique based on user input they should not be cached. The number of features returned from the query is also dynamic. Paging is used to ensure all features satisfying the query are returned. To enable paging, the result
and result
parameters of the query
operation are used.
Steps
- Get the hosted table URL and layer ID.
- Create and execute a SQL query.
- Display the paginated records.
let qs = []
for (let i = 0; i < totalRecords; i += recordOffset) {
const parcelQuery = {
where: whereClause,
outFields: Object.keys(outFields), // Attributes to return
orderByFields: ["yearbuilt1 ASC", "sqftmain1 ASC"],
num: returnCount, // paginate to return all records,
start: i, // set offSet
}
qs.push(parcelsTable.queryFeatures(parcelQuery))
}
Promise.all(qs).then(recs => {
recs.forEach((resp, ndx) => {
addToTable(resp, ndx === 0)
})
setLoading(false)
})
REST API
curl https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Santa_Monica_parcels_table/FeatureServer/0/query? \
-d "where=yearbuilt1 >= 2019 and sqftmain1 >= 4000 and bedrooms1 <= 4 and bathrooms1 >= 3" \
-d "outFields=APN, UseType, TaxRateCity, Roll_LandValue" \
-d "resultRecordCount=100" \
-d "resultOffset=0"
-d "f=json"
{
"objectIdFieldName": "OBJECTID",
"uniqueIdField": {
"name": "OBJECTID",
"isSystemMaintained": true
},
"globalIdFieldName": "",
"geometryType": "esriGeometryPolygon",
"spatialReference": {
"wkid": 102100,
Join a table to a feature layer
You can combine the attributes from one dataset to another based on attribute relationships which creates new feature data. In this example, you use the Join
operation from the spatial analysis service to join the Trailheads_data hosted table to the Trailheads_locations hosted feature layer. The resulting layer displays the corresponding attribute information for trailheads.
Steps
- Get the hosted table URL.
- Get the feature layer URL.
- Join the feature table to the feature layer.
- Display the resulting layer from the join.
APIs
const trailsResults = await trailsLayer.load().then(() => {
return trailsLayer.queryFeatures({
where: "1=1",
returnGeometry: true,
outFields: ["TRL_NAME"]
});
});
const tableResults = await tableLayer.load().then(() => {
return tableLayer.queryFeatures({
where: "1=1",
outFields: ["*"],
returnGeometry: false
});
});
const joinedAttFeatures = [];
trailsResults.features.forEach((trailsFeature) => {
tableResults.features.forEach((tableFeature) => {
if (trailsFeature.attributes["TRL_NAME"] === tableFeature.attributes["TRL_NAME"]) {
trailsFeature.attributes = { ...trailsFeature.attributes, ...tableFeature.attributes };
joinedAttFeatures.push(trailsFeature.clone());
}
})
});
const joinedLayer = new FeatureLayer({
id: "joined-layer",
source: joinedAttFeatures,
objectIdField: "ObjectId2",
fields: tableLayer.fields,
title: "Joined Layer",
geometryType: "point",
outFields: ["*"]
})
map.add(joinedLayer);
// Add layer to the feature table widget
const featureTable = new FeatureTable({
view: view,
layer: joinedLayer,
container: tableDiv,
hiddenFields: ["OBJECTID"]
});
Service requests
Request
POST arcgis.com/sharing/rest/portals/self HTTP/1.1
Content-Type: application/x-www-form-urlencoded
&f=json
&token=<ACCESS_TOKEN>
Response (JSON)
{
"helperServices": {
// Other parameters
"analysis": {
"url": "https://<YOUR_ANALYSIS_SERVICE>/arcgis/rest/services/tasks/GPServer"
},
"geoenrichment": {
"url": "https://geoenrich.arcgis.com/arcgis/rest/services/World/GeoenrichmentServer"
}
}
}
Request
POST <ANALYSIS_SERVICE>/arcgis/rest/services/tasks/GPServer/JoinFeatures/submitJob HTTP/1.1
Content-Type: application/x-www-form-urlencoded
f=json
&token=<ACCESS_TOKEN>
&targetLayer={"url":"https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads_locations/FeatureServer/0"}
&joinLayer={"url":"https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trailheads_data/FeatureServer/0"}
&joinOperation=joinOneToOne
&attributeRelationship=["{"targetField":"TRL_NAME","operator":"equal","joinField":"TRL_NAME"}"]
&recordsToMatch={"groupByFields":"","orderByFields":"OBJECTID ASC","topCount":1}
&joinType=inner
&outputName={"serviceProperties":{"name":"Join features sql result"}}
&context={"extent":{"xmin":-9745081.305501556,"ymin":3688856.7703679274,"xmax":-7938721.45306675,"ymax":4734515.317308861,"spatialReference":{"wkid":102100,"latestWkid":3857}}}
Response (JSON)
{
"jobId": "<JOB_ID>",
"jobStatus": "esriJobSubmitted",
"results": {},
"inputs": {},
"messages": []
}
Request
POST <ANALYSIS_SERVICE>/arcgis/rest/services/tasks/GPServer/JoinFeatures/jobs/j347a8b21b5d943fbb4600772f3b2043e HTTP/1.1
Content-Type: application/x-www-form-urlencoded
f=json
&token=<ACCESS_TOKEN>
Response (JSON)
{
"jobId": "<JOB_ID>",
"jobStatus": "esriJobSucceeded",
"results": {
"outputLayer": {
"paramUrl": "results/outputLayer"
}
},
"inputs": {},
"messages": []
}
Request
POST <ANALYSIS_SERVICE>/arcgis/rest/services/tasks/GPServer/JoinFeatures/jobs/j347a8b21b5d943fbb4600772f3b2043e/results/outputLayer HTTP/1.1
Content-Type: application/x-www-form-urlencoded
f=json
&token=<ACCESS_TOKEN>
Response (JSON)
{
"paramName": "outputLayer",
"dataType": "GPString",
"value": {
"url": "<RESULT_ITEM_URL>",
"itemId": "<RESULT_ITEM_ID>"
}
}
Tutorials

Add a feature layer
Access and display point, line, and polygon features from a feature service.

Add a vector tile layer
Access and display a vector tile layer in a map.

Add a map tile layer
Access and display a map tile layer in a map.

Style a feature layer
Use symbols and renderers to style feature layers.

Query a feature layer (spatial)
Execute a spatial query to get features from a feature layer.

Query a feature layer (SQL)
Execute a SQL query to access polygon features from a feature layer.

Edit feature data
Add, update, and delete features in a feature service.

Display a popup
Format a popup to show attributes in a feature layer.
Workflows
Create a feature service for an app
Learn how to import parcel data, create and style a feature layer, and then access the features in an app.

Create a feature layer view for an editor app
Learn how to import parcel data, create and style a feature layer view, and then access the features in an editing app.

Create a vector tile service for an app
Learn how to import parcel data, style a feature layer, and then create a vector tile service for an app.

Create a map tile service for an app
Learn how to import contour data, style a feature layer, and create a map tile service for an app.

Services
Feature service
Add, update, delete, and query feature data.
Vector tile service
Store and access vector tile data.
Map tile service
Store and access map tile data.
API support
Use Client APIs to create, manage, and access data services. The table below outlines the level of support for each API.
- 1. Use portal class and direct REST API requests
- 2. Access via ArcGIS REST JS
- 3. Requires manually setting styles for renderers