Query a feature layer (SQL)

Learn how to execute a SQL query to access polygon features from a feature layer.

A feature layer can contain a large number of features stored in ArcGIS. To access a subset of the features, you can execute either a SQL or spatial query, or both at the same time. You can return feature attributes, geometry, or both attributes and geometry for each record. SQL and spatial queries are useful when you want to access only a subset of your hosted data.

In this tutorial, you will perform server-side SQL queries to return a subset of features in the LA County Parcel feature layer. The feature layer contains over 2.4 million features. The resulting features are displayed as graphics on the map.

Prerequisites

You need an ArcGIS Developer or ArcGIS Online account to access the dashboard and create an API key.

Steps

Create a new pen

  1. To get started, either complete the Display a map tutorial or .

Set the API key

To access ArcGIS services, you need an API key.

  1. Go to your dashboard to get an API key.
  2. In CodePen, set the apiKey to your key, so it can be used to access basemap layer and location services.
Use dark colors for code blocks
1
2
3
4
esriConfig.apiKey = "YOUR_API_KEY";
const map = new Map({
  basemap: "arcgis/topographic" // basemap styles service
});

Add modules

  1. In the require statement, add the FeatureLayer module.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    require([
      "esri/config",
      "esri/Map",
      "esri/views/MapView",
      "esri/layers/FeatureLayer",
    ], function(esriConfig, Map, MapView, FeatureLayer) {
Expand

Create a SQL selector

ArcGIS feature layers support a standard SQL query where clause. Use an HTML select element to provide a list of SQL queries for the LA County Parcel feature layer.

  1. Create a parcelType array of SQL queries. Assign the whereClause element to a SQL query from the array.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      const view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-118.80543,34.03000], //Longitude, latitude
        zoom: 13
      });

      // SQL query array
      const parcelLayerSQL = ["Choose a SQL where clause...", "UseType = 'Residential'",  "UseType = 'Government'", "UseType = 'Irrigated Farm'", "TaxRateArea = 10853", "TaxRateArea = 10860", "TaxRateArea = 08637", "Roll_LandValue > 1000000", "Roll_LandValue < 1000000"];
      let whereClause = parcelLayerSQL[0];
Expand
  1. Create a parent select element and add option elements for each SQL query. Add some some basic styles to the elements.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      // SQL query array
      const parcelLayerSQL = ["Choose a SQL where clause...", "UseType = 'Residential'",  "UseType = 'Government'", "UseType = 'Irrigated Farm'", "TaxRateArea = 10853", "TaxRateArea = 10860", "TaxRateArea = 08637", "Roll_LandValue > 1000000", "Roll_LandValue < 1000000"];
      let whereClause = parcelLayerSQL[0];

      // Add SQL UI
      const select = document.createElement("select");
      select.setAttribute("class", "esri-widget esri-select");
      select.setAttribute("style", "width: 200px; font-family: 'Avenir Next'; font-size: 1em");
      parcelLayerSQL.forEach(function(query){
        let option = document.createElement("option");
        option.innerHTML = query;
        option.value = query;
        select.appendChild(option);
      });

Expand
  1. Add the select element to the top-right corner of the view.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      // Add SQL UI
      const select = document.createElement("select");
      select.setAttribute("class", "esri-widget esri-select");
      select.setAttribute("style", "width: 200px; font-family: 'Avenir Next'; font-size: 1em");
      parcelLayerSQL.forEach(function(query){
        let option = document.createElement("option");
        option.innerHTML = query;
        option.value = query;
        select.appendChild(option);
      });

      view.ui.add(select, "top-right");
Expand
  1. Add an event listener to listen for select element changes.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      view.ui.add(select, "top-right");

       // Listen for changes
      select.addEventListener('change', (event) => {
        whereClause = event.target.value;

      });
Expand
  1. Verify that the select element is created.

Create a feature layer to query

Use the FeatureLayer class to access the LA County Parcel feature layer. Since you are performing a server-side query, the feature layer does not need to be added to the map.

  1. Create a parcelLayer and set the url property to access the feature layer in the feature service.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
       // Listen for changes
      select.addEventListener('change', (event) => {
        whereClause = event.target.value;

      });

      // Get query layer and set up query
 const parcelLayer = new FeatureLayer({
        url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
      });
Expand

Execute a query

Use the queryFeatures method to perform a SQL query against the feature layer. The Query will be autocast when the method is called.

  1. Create a queryFeatureLayer function with extent parameter. Define a parcelQuery element and set the where property to the whereClause. Set the spatialProperty to only return features that intersect the geometry, which is restricted to the visible extent of the map. The outFields property will return only a subset of the attributes. Lastly, set returnGeometry to true so that the features can be displayed.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      // Get query layer and set up query
 const parcelLayer = new FeatureLayer({
        url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
      });

      function queryFeatureLayer(extent) {

        const parcelQuery = {
         where: whereClause,  // Set by select element
         spatialRelationship: "intersects", // Relationship operation to apply
         geometry: extent, // Restricted to visible extent of the map
         outFields: ["APN","UseType","TaxRateCity","Roll_LandValue"], // Attributes to return
         returnGeometry: true
        };

      }
Expand
  1. Call the queryFeatures method on the parcelLayer using parcelQuery. To view the number of features returned, write the result length to the console. This will be updated in the next step.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
      function queryFeatureLayer(extent) {

        const parcelQuery = {
         where: whereClause,  // Set by select element
         spatialRelationship: "intersects", // Relationship operation to apply
         geometry: extent, // Restricted to visible extent of the map
         outFields: ["APN","UseType","TaxRateCity","Roll_LandValue"], // Attributes to return
         returnGeometry: true
        };

        parcelLayer.queryFeatures(parcelQuery)

        .then((results) => {

          console.log("Feature count: " + results.features.length)

        }).catch((error) => {
          console.log(error.error);
        });

      }
Expand
  1. Update the event handler to call the queryFeatureLayer function when the selector changes.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
       // Listen for changes
      select.addEventListener('change', (event) => {
        whereClause = event.target.value;

        queryFeatureLayer(view.extent);

      });
Expand
  1. At the top-right, click Run. Choose a SQL query from the selector. At the bottom left, click Console to view the number of features returned from each query.

Display features

To display the features returned from the SQL query, add them to the view as polygon graphics. Define a pop-up also so the attributes can be displayed when features are clicked.

  1. Create a displayResults function with results as a parameter. Define a symbol and popupTemplate variable to style and display a pop-up for polygon graphics. The attributes referenced match the outFields specified in the query earlier.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        }).catch((error) => {
          console.log(error.error);
        });

      }

      function displayResults(results) {
        // Create a blue polygon
        const symbol = {
          type: "simple-fill",
          color: [ 20, 130, 200, 0.5 ],
          outline: {
            color: "white",
            width: .5
          },
        };

        const popupTemplate = {
          title: "Parcel {APN}",
          content: "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}"
        };

      }
Expand
  1. Assign the symbol and popupTemplate elements to each feature returned from the query.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        const popupTemplate = {
          title: "Parcel {APN}",
          content: "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}"
        };

        // Assign styles and popup to features
        results.features.map((feature) => {
          feature.symbol = symbol;
          feature.popupTemplate = popupTemplate;
          return feature;
        });

Expand
  1. Clear the existing graphics and pop-up, and then add the new features returned to the view.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        // Assign styles and popup to features
        results.features.map((feature) => {
          feature.symbol = symbol;
          feature.popupTemplate = popupTemplate;
          return feature;
        });

        // Clear display
        view.closePopup();
        view.graphics.removeAll();
        // Add features to graphics layer
        view.graphics.addMany(results.features);
Expand
  1. Update the queryFeatureLayer function to call the displayResults function. Remove the console.log.
Expand
Use dark colors for code blocks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
        parcelLayer.queryFeatures(parcelQuery)

        .then((results) => {

          console.log("Feature count: " + results.features.length)

          displayResults(results);

        }).catch((error) => {
          console.log(error.error);
        });
Expand

Run the app

In CodePen, run your code to display the map.

When the map displays, you should be able to choose a SQL query from the selector. The resulting features will be added to the map as polygon graphics. The SQL query is applied to the visible extent of the map.

What's next?

Learn how to use additional API features and ArcGIS services in these tutorials:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.