I tried searching but was surprised to not find any good results. Does anyone have a coding pattern to handle "paging" through a large query that exceeds the service's maxRecordCount property? I'd like to find a way to query the record count first, then build a bunch of query tasks with varying start and num properties to retrieve all the results. Promise.all() seems like it'd be what's needed but I can't quite wrap my head around how to make it all work. Here's my related question regarding distinct values that started this.
Blake,
Here is how I do that:
<SPAN class="keyword token">var</SPAN> iMaxRecords <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> featuresProcessed <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> featuresTotal <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> maxRecordCount <SPAN class="operator token">=</SPAN> layer<SPAN class="punctuation token">.</SPAN>maxRecordCount<SPAN class="punctuation token">;</SPAN> <SPAN class="comment token">//normally 1000</SPAN> queryTask <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">QueryTask</SPAN><SPAN class="punctuation token">(</SPAN>uri<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> cntQuery <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Query</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> cntQuery<SPAN class="punctuation token">.</SPAN>where <SPAN class="operator token">=</SPAN> <SPAN class="string token">"1=1"</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">executeForCount</SPAN><SPAN class="punctuation token">(</SPAN>cntQuery<SPAN class="punctuation token">,</SPAN> <SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>count<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">{</SPAN> featuresTotal <SPAN class="operator token">=</SPAN> count<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">if</SPAN><SPAN class="punctuation token">(</SPAN>count <SPAN class="operator token"><=</SPAN> maxRecordCount<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">//not an issue where you need to page</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="keyword token">else</SPAN><SPAN class="punctuation token">{</SPAN> query<SPAN class="punctuation token">.</SPAN>returnGeometry <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">false</SPAN><SPAN class="punctuation token">;</SPAN> query<SPAN class="punctuation token">.</SPAN>objectIds <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">;</SPAN> query<SPAN class="punctuation token">.</SPAN>where <SPAN class="operator token">=</SPAN> <SPAN class="string token">"1=1"</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">executeForIds</SPAN><SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">,</SPAN> onSearchIdsFinish<SPAN class="punctuation token">,</SPAN> onSearchError<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">function</SPAN> <SPAN class="token function">onSearchIdsFinish</SPAN><SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>results<SPAN class="punctuation token">.</SPAN>length <SPAN class="operator token">></SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> objectIdsArray <SPAN class="operator token">=</SPAN> results<SPAN class="punctuation token">;</SPAN> featuresTotal <SPAN class="operator token">=</SPAN> objectIdsArray<SPAN class="punctuation token">.</SPAN>length<SPAN class="punctuation token">;</SPAN> query<SPAN class="punctuation token">.</SPAN>where <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">;</SPAN> query<SPAN class="punctuation token">.</SPAN>text <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">null</SPAN><SPAN class="punctuation token">;</SPAN> query<SPAN class="punctuation token">.</SPAN>objectIds <SPAN class="operator token">=</SPAN> objectIdsArray<SPAN class="punctuation token">.</SPAN><SPAN class="token function">slice</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="number token">0</SPAN><SPAN class="punctuation token">,</SPAN> maxRecordCount<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">execute</SPAN><SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">,</SPAN> onSearchFinish<SPAN class="punctuation token">,</SPAN> onSearchError<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">else</SPAN> <SPAN class="punctuation token">{</SPAN> console<SPAN class="punctuation token">.</SPAN><SPAN class="token function">error</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="string token">'onSearchIdsFinish returned zero length'</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> isQuerying <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">false</SPAN><SPAN class="punctuation token">;</SPAN> esc <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">false</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">function</SPAN> <SPAN class="token function">onSearchFinish</SPAN><SPAN class="punctuation token">(</SPAN>featureSet<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// do something with the results</SPAN> featuresProcessed <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> featureSet<SPAN class="punctuation token">.</SPAN>features<SPAN class="punctuation token">.</SPAN>length<SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>iMaxRecords <SPAN class="operator token">===</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> iMaxRecords <SPAN class="operator token">=</SPAN> featuresProcessed<SPAN class="punctuation token">;</SPAN> iStart <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> iMaxRecords<SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">if</SPAN> <SPAN class="punctuation token">(</SPAN>iStart <SPAN class="operator token"><</SPAN> objectIdsArray<SPAN class="punctuation token">.</SPAN>length<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">//If we get this far we need to requery the server for the next lot of records</SPAN> query<SPAN class="punctuation token">.</SPAN>objectIds <SPAN class="operator token">=</SPAN> objectIdsArray<SPAN class="punctuation token">.</SPAN><SPAN class="token function">slice</SPAN><SPAN class="punctuation token">(</SPAN>iStart<SPAN class="punctuation token">,</SPAN> iStart <SPAN class="operator token">+</SPAN> iMaxRecords<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">execute</SPAN><SPAN class="punctuation token">(</SPAN>query<SPAN class="punctuation token">,</SPAN> onSearchFinish<SPAN class="punctuation token">,</SPAN> onSearchError<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> iStart <SPAN class="operator token">+</SPAN><SPAN class="operator token">=</SPAN> iMaxRecords<SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
Interesting approach, thanks. My feature layer (hosted at 10.5.1) doesn't have a maxRecordCount property. It doesn't even have a capabilities property. Any thoughts on that?
After posting I got something that I think works. Besides the fact it doesn't work with returnDistinctValues (as I mentioned before), I'm not sure how I feel about it.
<SPAN class="keyword token">var</SPAN> maxRecordCount <SPAN class="operator token">=</SPAN> <SPAN class="number token">1000</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> queryTask <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">QueryTask</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN>url <SPAN class="operator token">=</SPAN> <SPAN class="string token"><SPAN>'</SPAN><A class="jive-link-external-small" href="https://community.esri.com/external-link.jspa?url=http%3A%2F%2Fserver%2Farcgis%2Frest%2Fservices%2FServiceName%2FMapServer%2F0" target="_blank">http://server/arcgis/rest/services/ServiceName/MapServer/0</A><SPAN>'</SPAN></SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> queryParams <SPAN class="operator token">=</SPAN> <SPAN class="keyword token">new</SPAN> <SPAN class="token class-name">Query</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="punctuation token">{</SPAN> returnGeometry<SPAN class="punctuation token">:</SPAN> <SPAN class="keyword token">false</SPAN><SPAN class="punctuation token">,</SPAN> outFields<SPAN class="punctuation token">:</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="string token">'someFieldName'</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">,</SPAN> where<SPAN class="punctuation token">:</SPAN> <SPAN class="string token">'someFieldName is not null'</SPAN><SPAN class="punctuation token">,</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">executeForCount</SPAN><SPAN class="punctuation token">(</SPAN>queryParams<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="token function">then</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>queryRecordCount<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="keyword token">var</SPAN> pageCount <SPAN class="operator token">=</SPAN> Math<SPAN class="punctuation token">.</SPAN><SPAN class="token function">ceil</SPAN><SPAN class="punctuation token">(</SPAN>queryRecordCount <SPAN class="operator token">/</SPAN> maxRecordCount<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">var</SPAN> resultPages <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">for</SPAN> <SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">var</SPAN> i <SPAN class="operator token">=</SPAN> <SPAN class="number token">0</SPAN><SPAN class="punctuation token">;</SPAN> i <SPAN class="operator token"><</SPAN> pageCount<SPAN class="punctuation token">;</SPAN> i<SPAN class="operator token">++</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> resultPages<SPAN class="punctuation token">.</SPAN><SPAN class="token function">push</SPAN><SPAN class="punctuation token">(</SPAN>i <SPAN class="operator token">*</SPAN> maxRecordCount<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN> <SPAN class="keyword token">return</SPAN> Promise<SPAN class="punctuation token">.</SPAN><SPAN class="token function">all</SPAN><SPAN class="punctuation token">(</SPAN>resultPages<SPAN class="punctuation token">.</SPAN><SPAN class="token function">map</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>resultPageStart<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">{</SPAN> queryParams<SPAN class="punctuation token">.</SPAN>start <SPAN class="operator token">=</SPAN> resultPageStart<SPAN class="punctuation token">;</SPAN> queryParams<SPAN class="punctuation token">.</SPAN>num <SPAN class="operator token">=</SPAN> maxRecordCount <SPAN class="operator token">-</SPAN> <SPAN class="number token">1</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="keyword token">return</SPAN> queryTask<SPAN class="punctuation token">.</SPAN><SPAN class="token function">execute</SPAN><SPAN class="punctuation token">(</SPAN>queryParams<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="token function">then</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>featureSets<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> <SPAN class="comment token">// collect features from each FeatureSet</SPAN> <SPAN class="keyword token">var</SPAN> features <SPAN class="operator token">=</SPAN> <SPAN class="punctuation token">[</SPAN><SPAN class="punctuation token">]</SPAN><SPAN class="punctuation token">;</SPAN> featureSets<SPAN class="punctuation token">.</SPAN><SPAN class="token function">forEach</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>featureSet<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> features <SPAN class="operator token">=</SPAN> features<SPAN class="punctuation token">.</SPAN><SPAN class="token function">concat</SPAN><SPAN class="punctuation token">(</SPAN>featureSet<SPAN class="punctuation token">.</SPAN>features<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="comment token">// do something with array of features</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">.</SPAN><SPAN class="keyword token">catch</SPAN><SPAN class="punctuation token">(</SPAN><SPAN class="keyword token">function</SPAN><SPAN class="punctuation token">(</SPAN>err<SPAN class="punctuation token">)</SPAN> <SPAN class="punctuation token">{</SPAN> console<SPAN class="punctuation token">.</SPAN><SPAN class="token function">error</SPAN><SPAN class="punctuation token">(</SPAN>err<SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN> <SPAN class="punctuation token">}</SPAN><SPAN class="punctuation token">)</SPAN><SPAN class="punctuation token">;</SPAN><SPAN class="line-numbers-rows"><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN><SPAN></SPAN></SPAN>
You can use QueryTask.exectueForCount() and in the Query object you can use returnDistinct. This will allow you to get a number that is in fact the real distinct count for your query. You then can decide if you need to use the paging route. Also the query result returns a exceededTransferLimit property that tells you if your results are not all the distinct data.
Signed in members can post, follow updates, and more. New here? Register a free account.
Find useful guides, FAQs, and documents to help you navigate and make the most of Esri Community.