This topic provides an overview of the many workflows you can use for querying and filtering data. Query and filter operations can be done against all features available in the service on the server-side or against all features available in the browser (or view) on the client-side.
First, we will review which layers allow you to query and filter subsets of features. In doing so, we must understand the concept of server-side vs client-side layers, and Layer vs LayerView.
Server-side and client-side layers
The ArcGIS Maps SDK for JavaScript makes it possible for you to add data from many sources. Layers that allow you to query and filter subsets of their features can be grouped into server-side layers and client-side layers.
Server-side layers fetch only required features when they load. Afterwards, layers fetch their features from the server as needed or requested. These layers include: FeatureLayer,
OGCFeatureLayer, SceneLayer and StreamLayer. The server-side layer is created by setting the layer's url
property to point to a service.
Client-side layers fetch all of their features at once and store them on the client-side when they load. Once these layers are loaded, there will be no more server-side requests. These layers include: CSVLayer, GeoJSONLayer and WFSLayer. They are created by setting the layer's url
property to a csv or geojson file, or the WFS service. It also includes a FeatureLayer created from an array of client-side graphics by setting its source property.
Layer and LayerView
A LayerView is created when a layer is added to either a MapView or a SceneView. The LayerView is responsible for rendering features in the view. The layerView also provides methods and properties that give developers the ability to query, filter, and highlight graphics in the view on the client-side.
The following table shows a simplified steps that take place when the user adds a layer to a view.
Behavior | Server-side layers | Client-side layers |
---|---|---|
Layers | CSVLayer, GeoJSONLayer, WFSLayer and client-side FeatureLayer | |
Initialization | Created by setting its url property to point to a server-side feature, scene, or stream service.
| CSVLayer, GeoJSONLayer, and WFSLayer are created by setting their url property. Client-side FeatureLayer is created by setting its source property.
|
Initial features fetching | The layer fetches only required features from the server. | The layer fetches all of its features when initialized and stores it on the client. |
LayerView initialization | FeatureLayerView, OGCFeatureLayerView, SceneLayerView or StreamLayerView representing FeatureLayer, OGCFeatureLayer, SceneLayer or StreamLayer is initialized containing features available for drawing.
| CSVLayerView, GeoJSONLayerView FeatureLayerView or WFSLayerView representing CSVLayer, GeoJSONLayer, FeatureLayer or WFSLayer is initialized containing features available for drawing.
|
Subsequent network requests | Yes. Subsequent network requests are made as needed. | No if the layer is not refreshed after loading.
|
The following image illustrates the features available for querying from a layer and a layerView. As you can see the layer has features covering much more area than the initial extent of the application. The layer properties and methods provide access to all of these features. When the layer is loaded, the layerView has access to features that are visible within the app's initial extent. Any operation called on the layerView after the app loads provides access to features visible in the view. The image also shows the count of features available on the layer versus on the layerView. The layerView feature count is much less because it returns features within the initial extent of the view while layer count represents all features in the layer.
Querying
There are three types of queries: attribute, spatial, and statistic. This document provides detailed information on each type of query. Queries can be done on the layer or on its layerView.
Server-side queries
A server-side query is issued when a query...
method is called on a server-side layer. The query is executed against all features available in the service.
(Feature|Scene)Layer // queries all features in the service
.queryFeatures() // queries all features and returns a FeatureSet
.queryExtent() // queries all features returns extent of features that satisfy query
.queryFeatureCount() // queries all features and returns count of features
.queryObjectIds() // queries all features and returns objectIds array of features
Client-side queries
A client-side query is issued when a query...
method is called on a client-side layer or any layerView. The query is executed against all features available in the layer or layerView.
(Feature|CSV|GeoJSON|WFS)Layer // queries all features in the layer
(Feature|CSV|GeoJSON|OGCFeature|Scene|Stream)LayerView // queries available features in view
.queryFeatures() // queries features and returns a FeatureSet
.queryExtent() // queries features returns extent of features that satisfy query
.queryFeatureCount() // queries features and returns count of features
.queryObjectIds() // queries features and returns objectIds array of features
Should I use client-side query or server-side query?
What matters? | Server side query | Client-side query |
---|---|---|
Speed and responsiveness | No for server-side layers. You are making network requests, so it is slower compared to client-side queries. | Yes for client-side layers and layerViews. |
Geometry precision | Yes. Geometry precision is preserved. Use when it is important to get accurate results with a precise geometry. | Yes for client-side layers to query user provided geometries. No for layerViews as geometries are generalized for drawing. The results can be imprecise and change as the user zooms in the map. Examples include calculating an area for selected geometries, or getting points contained in a polygon. |
Must query every feature | Yes. Use a server-side query to make sure that the query runs against all features. Paginated queries must be done when you need to get more than max record count. | Yes for CSVLayer, GeoJSONLayer and client-side FeatureLayer. No for layerViews as the query will only run against features that are available on the client-side. |
Tips when using query methods on LayerViews
- Add fields to a layer's outFields at the time of the layer initialization to ensure that you have access to these fields on the client-side. By default the layerView only fetches the fields that are required for layer rendering, labeling, elevation info.
- If you query a layerView when the app loads, then you must wait until layerView's updating property becomes
false
to make sure that the features are loaded with the layerView. You can use reactiveUtils.whenOnce if the query needs to run only once at the time of initialization. - If you query a layerView each time the view extent changes, then you must wait until the layerView's updating property becomes
false
to make sure the layerView finished fetching the features for that extent. - The client-side attribute values are case sensitive.
Use the query tag to explore all samples that demonstrate these concepts. This tutorial walks through querying FeatureLayer and FeatureLayerView.
Filtering
Filters affect the availability of features in a layer or the visibility of features in a layerView. Features that satisfy the filter requirements will be displayed in the view. Filtering can take place on the server-side or on the client-side.
Server-side filtering
All layers covered in this guide have a definitionExpression property. Setting a definition
on a server-side layer triggers a network request to fetch features that satisfy the definition expression. Setting a definition expression is useful when the dataset is large and you don't want to bring all features to the client for analysis. If the definition expression is set after the layer has been added to the map, the view will automatically refresh itself to display the features that satisfy the new definition expression.
// fetch all features that satisfy requirements from the service
(Feature|Scene|Stream)Layer
.definitionExpression = "type = 'metal'";
Client-side filtering
A definition
on a client-side layer will only display features that satisfy the definitionExpression. Setting a definitionExpression happens on the client-side against all features available in the layer.
// only display features that satisfy the requirements in the layer
(Feature|CSV|GeoJSON|WFS)Layer
.definitionExpression = "mag > 5";
If a layer has a definition
, all layerView queries and filters will honor the definition
. This means only features that meet the layer's definition
will be evaluated by the layerView's query and filter operations.
You can apply filters on features available for drawing by setting a filter
on a LayerView. The FeatureFilter allows you to display the features that satisfy the filter requirements in the layerView. Since the filter is applied to a layerView, this happens on the client-side against features that are available for drawing.
(Feature|CSV|GeoJSON|OFCFeature|Scene|Stream|WFS)LayerView
// only display features that satisfy the requirements in the layer
.filter = new FeatureFilter({
where: "age > 25";
});
Filters can be applied based on attributes, time, and/or geometry. Search the sample code using the FeatureFilter tag to explore all current samples that demonstrate how you can use the feature
to display subset of features that meet requirements. This tutorial walks through querying and filtering on a FeatureLayer. Also check out this sample for the FeatureFilter in a scene: Filter SceneLayer with FeatureFilter.
In the case of SceneLayers, you can apply filters on features by setting a filter directly on the layer. The SceneFilter allows you to display the features that satisfy the filter requirements in the layer and also persist this information in a WebScene or on the SceneLayer. Even though the filter is applied to a layer, the filtering still happens on the client-side.
// only display features that satisfy the requirements in the layer
SceneLayer.filter = new SceneFilter({
geometries: [polygon1, polygon2],
spatialRelationship: "contains"
});
SceneFilters accept a list of geometries and a certain spatialRelationship. For more information, see this sample: Filter SceneLayer with SceneFilter.
You can also apply FeatureEffect to FeatureLayer, CSVLayer, GeoJSONLayer, OGCFeatureLayer, StreamLayer and WFSLayer or to FeatureLayerView, CSVLayerView, GeoJSONLayerView, OGCFeatureLayerView, StreamLayerView or WFSLayerView to draw attention features of interest. It applies different effects to features when a filter is set on the layer or layerView. The includedEffect is applied to those features that pass the filter requirements. The excludedEffect is applied to those features fail the filter requirements.
(Feature|CSV|GeoJSON|OFCFeature|Stream|WFS)LayerView
// gray out features that fall outside of the 3 mile buffer of the mouse's location
// by setting feature effect on excluded features
.featureEffect = new FeatureEffect({
filter: new FeatureFilter({
geometry: filterGeometry,
spatialRelationship: "intersects",
distance: 3,
units: "miles"
}),
excludedEffect: "grayscale(100%) opacity(30%)"
});
(Feature|CSV|GeoJSON|OFCFeature|Stream|WFS)LayerView
// Apply a drop-shadow feature effect to the features that have population greater than one million,
// while applying blur and brightness effects to the features that are excluded from filter criteria.
// The resulting map will make it easier to spot areas with population greater than one million.
.featureEffect = new FeatureEffect({
filter: new FeatureFilter({
where: "POPULATION > 1000000"
}),
includedEffect: "drop-shadow(3px, 3px, 3px, black)",
excludedEffect: "blur(1px) brightness(65%)"
});
Use the effect tag to explore all samples that demonstrate these concepts.