Hello everyone,
We are running ArcGIS Enterprise 11.5 and I am looking to automate the process of rebuilding spatial indexes for hosted feature layers.
I am aware that this can be done manually through the Portal UI by going to the hosted feature layer item → Settings → Feature Layer (Hosted) → Indexes, where the spatial index can be rebuilt. Since this functionality exists and is supported in the Portal interface, I assume it is calling some internal operation.
However, I have not been able to find any documented or supported way to trigger the same spatial index rebuild programmatically using the REST API, ArcGIS API for Python, or a geoprocessing tool. I did come across the following community post, but it is unclear whether it applies only to ArcGIS Online or if it is relevant to ArcGIS Enterprise as well:
https://community.esri.com/t5/arcgis-online-questions/automate-task-to-rebuild-spatial-index-of-host...
Has anyone identified a supported method to automate the same spatial index rebuild that is available in the Portal UI for hosted feature layers in ArcGIS Enterprise? Or is this currently only possible through manual interaction in the Portal?
Any insights or confirmation would be greatly appreciated. Thank you.
Solved! Go to Solution.
Hello @ZenMasterZeke ,
Thanks a lot for the example, it helped a lot.
What I managed to do is to convert it to check for all hosted services in the Enterprise Portal and rebuild the spatial index for those with Sync disabled, please see it below:
"from arcgis.gis import GIS
from arcgis.features import FeatureLayerCollection
import datetime
# Configuration
PORTAL_URL = "https://your-portal-url/portal"
USERNAME = "admin_user"
PASSWORD = "admin_password"
print(f"Connecting to {PORTAL_URL}...")
gis = GIS(PORTAL_URL, USERNAME, PASSWORD, verify_cert=False)
print(f"Connected as: {gis.properties.user.username}\n")
# Search for hosted feature services (excluding views)
print("Searching for hosted feature services...")
items = gis.content.search(
query="type:'Feature Service' AND typekeywords:Hosted AND -typekeywords:'View Service'",
max_items=1000,
outside_org=False
)
print(f"Found {len(items)} hosted feature services\n")
print("="*80)
# Tracking
services_checked = 0
layers_rebuilt = 0
services_skipped_sync = 0
layers_skipped_no_index = 0
layers_failed = []
for item in items:
services_checked += 1
print(f"\n[{services_checked}/{len(items)}] {item.title} (Owner: {item.owner})")
try:
flc = FeatureLayerCollection.fromitem(item)
# Check sync
if flc.properties.get('syncEnabled') or 'Sync' in flc.properties.get('capabilities', ''):
print(" ⏭ SKIPPED: Sync enabled")
services_skipped_sync += 1
continue
# Process each spatial layer
for lyr in flc.layers:
layer_name = lyr.properties.get('name', 'Unknown')
print(f" └─ Layer: {layer_name}")
# Get indexes from layer properties
indexes = lyr.properties.get("indexes", [])
# Find the spatial index - case-insensitive check for "shape"
spatial_idx = next((idx for idx in indexes if idx.get("fields", "").lower() == "shape"), None)
if not spatial_idx:
print(f" ⚠ No spatial index found, skipping")
layers_skipped_no_index += 1
continue
# Rebuild by passing existing index definition back
try:
payload = {"indexes": [{"name": spatial_idx["name"], "fields": spatial_idx["fields"]}]}
result = lyr.manager.update_definition(payload)
if result.get('success'):
print(f" ✓ Spatial index '{spatial_idx['name']}' rebuilt successfully")
layers_rebuilt += 1
else:
print(f" ✗ FAILED: {result}")
layers_failed.append(f"{item.title}/{layer_name}: {result}")
except Exception as e:
print(f" ✗ EXCEPTION: {e}")
layers_failed.append(f"{item.title}/{layer_name}: {e}")
except Exception as e:
print(f" ! ERROR: {e}")
layers_failed.append(f"{item.title}: {e}")
# Summary
print("\n" + "="*80)
print("SUMMARY")
print("="*80)
print(f"Services checked: {services_checked}")
print(f"Layers rebuilt: {layers_rebuilt}")
print(f"Services skipped (sync): {services_skipped_sync}")
print(f"Layers skipped (no index): {layers_skipped_no_index}")
print(f"Failed: {len(layers_failed)}")
if layers_failed:
print("\nFailed operations:")
for failed in layers_failed:
print(f" - {failed}")
print(f"\nCompleted: {datetime.datetime.now()}")"