Working with indexes


Summary
This topic discusses how to inspect the attribute and spatial indexes of a table or feature class.


About working with indexes

Each table in a geodatabase has a collection of indexes. The collection behaves like a list, making it possible to access indexes by their number positions. To access an index collection from a table, use the IClass.Indexes property (inherited by ITable and IFeatureClass). The following illustration shows the relationship between tables, index collections, and indexes:
The following code example shows how to determine the number of indexes a table has:
[C#]
public void DisplayIndexCount(ITable table)
{
    IIndexes indexes = table.Indexes;
    Console.WriteLine("The table has an index count of {0}.", indexes.IndexCount);
}
[VB.NET]
Public Sub DisplayIndexCount(ByVal table As ITable)
    
    Dim indexes As IIndexes = table.Indexes
    Console.WriteLine("The table has an index count of {0}.", indexes.IndexCount)
    
End Sub

Attribute indexes

Attribute indexes include a field set with one or more fields from a table. The field order determines the field that is used first when resolving queries. There is a limit of 10 fields in a geodatabase attribute index.
In most cases, file geodatabases can only have single-field indexes. The exception to this is when short integer and integer fields are used, in which case a multi-field index can be created using two fields.
For geodatabases, one attribute index is automatically created, that is, an index for the ObjectID field. Indexes created in the native environment of the database management system (DBMS) can also be accessed.
The following code example iterates through the index collection of a feature class. For each attribute index, it prints the list of field names the index is associated with:
[C#]
// This method displays the fields associated with each class's indexes.
public void DisplayAttributeIndexFields(IFeatureClass featureClass)
{
    // Get the collection of indexes.
    IIndexes indexes = featureClass.Indexes;

    // Iterate through the indexes.
    for (int i = 0; i < indexes.IndexCount; i++)
    {
        // Get the fields collection and first field of the index.
        IIndex index = indexes.get_Index(i);
        IFields fields = index.Fields;
        IField field = fields.get_Field(0);

        // If the field isn't a shape field, display the index's name and its fields.
        if (field.Type != esriFieldType.esriFieldTypeGeometry)
        {
            Console.WriteLine("Index Name: {0}", index.Name);
            for (int j = 0; j < fields.FieldCount; j++)
            {
                field = fields.get_Field(j);
                Console.WriteLine("Associated Field {0}: {1}", j, field.Name);
            }
        }
    }
}
[VB.NET]
' This method displays the fields associated with each class's indexes.

Public Sub DisplayAttributeIndexFields(ByVal featureClass As IFeatureClass)
    
    ' Get the collection of indexes.
    Dim indexes As IIndexes = featureClass.Indexes
    
    ' Iterate through the indexes.
    For i As Integer = 0 To indexes.IndexCount - 1
        ' Get the fields collection and first field of the index.
        Dim index As IIndex = indexes.Index(i)
        Dim fields As IFields = index.Fields
        Dim field As IField = fields.Field(0)
        
        ' If the field isn't a shape field, display the index's name and its fields.
        If field.Type <> esriFieldType.esriFieldTypeGeometry Then
            Console.WriteLine("Index Name: {0}", index.Name)
            
            For j As Integer = 0 To fields.FieldCount - 1
                field = fields.Field(j)
                Console.WriteLine("Associated Field {0}: {1}", j, field.Name)
            Next j
            
        End If
    Next i
    
End Sub
The IIndexes.FindIndexesByFieldName method can be used to find all indexes using a specific field. The following code example shows how to delete all of the indexes from a feature class given a specific field:
[C#]
public void DeleteIndexesByFieldName(IFeatureClass featureClass, String nameOfField)
{
    // Find all indexes associated with a specific field.
    IIndexes indexes = featureClass.Indexes;
    IEnumIndex enumIndex = indexes.FindIndexesByFieldName(nameOfField);

    // Attempt to acquire an exclusive schema lock on the feature class.
    ISchemaLock schemaLock = (ISchemaLock)featureClass;
    try
    {
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);

        // Iterate through and delete returned indexes.
        IIndex index = null;
        while ((index = enumIndex.Next()) != null)
        {
            featureClass.DeleteIndex(index);
        }
    }
    catch (COMException comExc)
    {
        // Handle appropriately for your application.
        Console.WriteLine("A COM Exception was thrown: {0}", comExc.Message);
    }
    finally
    {
        schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
    }
}
[VB.NET]
Public Sub DeleteIndexesByFieldName(ByVal featureClass As IFeatureClass, ByVal nameOfField As String)
    
    ' Find all indexes associated with a specific field.
    Dim indexes As IIndexes = featureClass.Indexes
    Dim enumIndex As IEnumIndex = indexes.FindIndexesByFieldName(nameOfField)
    
    ' Attempt to acquire an exclusive schema lock on the feature class.
    Dim schemaLock As ISchemaLock = CType(featureClass, ISchemaLock)
    Try
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock)
    ' Iterate through and delete returned indexes.
    Dim index As IIndex = Nothing
    Do While Not (index) Is Nothing
        featureClass.DeleteIndex(index)
        index = enumIndex.Next()
    Loop
    Catch comExc As COMException
    ' Handle appropriately for your application.
    Console.WriteLine("A COM Exception was thrown: {0}", comExc.Message)
    Finally
    schemaLock.ChangeSchemaLock(esriSchemaLock.esriSharedSchemaLock)
    End Try
    
End Sub
The IIndexes.FindIndex method can be used to return the position of an index in the Indexes collection given its name. The index can then be retrieved from the collection via the returned integer value. See the following code example:
[C#]
public IIndex GetIndexByName(IIndexes indexes, String indexName)
{
    int indexPosition =  - 1;
    indexes.FindIndex(indexName, out indexPosition);
    IIndex index = indexes.get_Index(indexPosition);
    return index;
}
[VB.NET]
Public Function GetIndexByName(ByVal indexes As IIndexes, ByVal indexName As String) As IIndex
    
    Dim indexPosition As Integer = -1
    indexes.FindIndex(indexName, indexPosition)
    Dim index As IIndex = indexes.Index(indexPosition)
    
    Return index
    
End Function

Spatial indexes

Spatial indexes exist on the Shape field of a feature class. Some of the spatial index properties—for example, the grid size—are only accessible through the GeometryDef object available from the Shape field. The spatial index is created automatically when a geodatabase feature class is created; therefore, it is not required that the spatial index be built using ArcObjects.
To view the grid count and grid size or sizes of an existing spatial index, get the properties of the GeometryDef from the feature class's shape field, as shown in the following code example:
[C#]
public void DisplaySpatialIndexProperties(IFeatureClass featureClass)
{
    // Find the shape field from the class's field set.
    String shapeFieldName = featureClass.ShapeFieldName;
    int shapeFieldIndex = featureClass.FindField(shapeFieldName);
    IFields fields = featureClass.Fields;
    IField shapeField = fields.get_Field(shapeFieldIndex);

    // Get the name of the spatial index, if one exists.
    IIndexes indexes = featureClass.Indexes;
    IEnumIndex enumIndex = indexes.FindIndexesByFieldName(shapeFieldName);
    enumIndex.Reset();
    IIndex spatialIndex = enumIndex.Next();
    if (spatialIndex == null)
    {
        Console.WriteLine("No spatial index exists.");
        return ;
    }
    Console.WriteLine("Spatial index name: {0}", spatialIndex.Name);

    // Get the shape field's GeometryDef and inspect its properties.
    IGeometryDef geometryDef = shapeField.GeometryDef;
    int gridCount = geometryDef.GridCount;
    Console.WriteLine("Grid count: {0}", gridCount);
    for (int i = 0; i < gridCount; i++)
    {
        double gridSize = geometryDef.get_GridSize(i);
        Console.WriteLine("Grid[{0}] size: {1}", i, gridSize);
    }
}
[VB.NET]
Public Sub DisplaySpatialIndexProperties(ByVal featureClass As IFeatureClass)
    ' Find the shape field from the class's field set.
    Dim shapeFieldName As String = featureClass.ShapeFieldName
    Dim shapeFieldIndex As Integer = featureClass.FindField(shapeFieldName)
    Dim fields As IFields = featureClass.Fields
    Dim shapeField As IField = fields.Field(shapeFieldIndex)
    
    ' Get the name of the spatial index, if one exists.
    Dim indexes As IIndexes = featureClass.Indexes
    Dim enumIndex As IEnumIndex = indexes.FindIndexesByFieldName(shapeFieldName)
    enumIndex.Reset()
    Dim spatialIndex As IIndex = enumIndex.Next()
    If spatialIndex Is Nothing Then
        Console.WriteLine("No spatial index exists.")
        Return
    End If
    Console.WriteLine("Spatial index name: {0}", spatialIndex.Name)
    
    ' Get the shape field's GeometryDef and inspect its properties.
    Dim geometryDef As IGeometryDef = shapeField.GeometryDef
    Dim gridCount As Integer = geometryDef.GridCount
    Console.WriteLine("Grid count: {0}", gridCount)
    Dim i As Integer
    For i = 0 To gridCount - 1
        Dim gridSize As Double = geometryDef.GridSize(i)
        Console.WriteLine("Grid[{0}] size: {1}", i, gridSize)
    Next i
End Sub


See Also:

Working with fields
Creating fields
Using schema locks




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Additional Requirements
  • If working in ArcSDE, a Standard or an Advanced license is required if using ArcGIS for Desktop, and the Geodatabase Update extension is required if using ArcGIS Engine.

Development licensing Deployment licensing
ArcGIS for Desktop Basic ArcGIS for Desktop Basic
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine