Creating indexes


Summary
This topic contains information on how to create attribute indexes, and how to create and rebuild spatial indexes. It also discusses how to delete indexes.


Creating an attribute index

The following are the two steps to creating an attribute index on a dataset:
  • The Index class and the IIndexEdit interface are used to create an object, which specifies the properties of the index to be created.
  • The IClass.AddIndex method (inherited by ITable and IFeatureClass) is used to actually create the index.
An attribute index contains a field set of one or more fields. For details on how to create a field set, see Creating fields.
The following code example demonstrates how to create an index for a single field:
[C#]
public void AddIndexToFeatureClass(IFeatureClass featureClass, String indexName,
    String nameOfField)
{
    // Ensure the feature class contains the specified field.
    int fieldIndex = featureClass.FindField(nameOfField);
    if (fieldIndex ==  - 1)
    {
        throw new ArgumentException(
            "The specified field does not exist in the feature class.");
    }

    // Get the specified field from the feature class.
    IFields featureClassFields = featureClass.Fields;
    IField field = featureClassFields.get_Field(fieldIndex);

    // Create a fields collection and add the specified field to it.
    IFields fields = new FieldsClass();
    IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
    fieldsEdit.FieldCount_2 = 1;
    fieldsEdit.set_Field(0, field);

    // Create an index and cast to the IIndexEdit interface.
    IIndex index = new IndexClass();
    IIndexEdit indexEdit = (IIndexEdit)index;

    // Set the index's properties, including the associated fields.
    indexEdit.Fields_2 = fields;
    indexEdit.IsAscending_2 = false;
    indexEdit.IsUnique_2 = false;
    indexEdit.Name_2 = indexName;

    // Add the index to the feature class.
    featureClass.AddIndex(index);
}
[VB.NET]
Public Sub AddIndexToFeatureClass(ByVal featureClass As IFeatureClass, ByVal indexName As String, ByVal nameOfField As String)
    ' Ensure the feature class contains the specified field.
    Dim fieldIndex As Integer = featureClass.FindField(nameOfField)
    If fieldIndex = -1 Then
        Throw New ArgumentException("The specified field does not exist in the feature class.")
    End If
    
    ' Get the specified field from the feature class.
    Dim featureClassFields As IFields = featureClass.Fields
    Dim field As IField = featureClassFields.Field(fieldIndex)
    
    ' Create a fields collection and add the specified field to it.
    Dim fields As IFields = New FieldsClass()
    Dim fieldsEdit As IFieldsEdit = CType(fields, IFieldsEdit)
    fieldsEdit.FieldCount_2 = 1
    fieldsEdit.Field_2(0) = field
    
    ' Create an index and cast to the IIndexEdit interface.
    Dim index As IIndex = New IndexClass()
    Dim indexEdit As IIndexEdit = CType(index, IIndexEdit)
    
    ' Set the index's properties, including the associated fields.
    indexEdit.Fields_2 = fields
    indexEdit.IsAscending_2 = False
    indexEdit.IsUnique_2 = False
    indexEdit.Name_2 = indexName
    
    ' Add the index to the feature class.
    featureClass.AddIndex(index)
End Sub

Deleting an index

To delete an index, retrieve an IIndex reference for the index to be deleted (for information on getting existing indexes from a dataset, see Working with indexes), then call the IClass.DeleteIndex method (as with AddIndex, this is inherited by ITable and IFeatureClass). See the following code example:
[C#]
public void DeleteIndexByName(IFeatureClass featureClass, String indexName)
{
    // Find the index with the specified name.
    IIndexes indexes = featureClass.Indexes;
    int indexPos = 0;
    indexes.FindIndex(indexName, out indexPos);
    if (indexPos < 0)
    {
        throw new ArgumentException("No index exists with the specified name.");
    }
    IIndex index = indexes.get_Index(indexPos);

    // Delete the index.
    featureClass.DeleteIndex(index);
}
[VB.NET]
Public Sub DeleteIndexByName(ByVal featureClass As IFeatureClass, ByVal indexName As String)
    ' Find the index with the specified name.
    Dim indexes As IIndexes = featureClass.Indexes
    Dim indexPos As Integer = 0
    indexes.FindIndex(indexName, indexPos)
    If indexPos < 0 Then
        Throw New ArgumentException("No index exists with the specified name.")
    End If
    Dim index As IIndex = indexes.Index(indexPos)
    
    ' Delete the index.
    featureClass.DeleteIndex(index)
End Sub

Creating and rebuilding a spatial index

Creating a spatial index is nearly identical to creating an attribute index, except that the field set can only contain a single field (the feature class's shape field). To specify the grid count (and the size of each grid) in a new spatial index, get a reference to the class's shape field, clone it, modify its GeometryDef as needed, then use the cloned field in the index's field set.
When setting the grid size of a spatial index with the IGeometryDefEdit.GridSize property, using a value of 0 lets ArcGIS determine the grid size automatically. In most cases, this is acceptable.
It is not possible to re-create the spatial index on a feature class in a personal geodatabase.
When setting the GridSize property of an R-Tree spatial index (for example, Oracle Spatial, Informix, and PostgreSQL), use a value of 0. Once created, this property returns a value of -2 for these indexes.
To rebuild a spatial index, delete a class's existing spatial index, then create a new one. The following code example shows how to do this:
[C#]
// Passing zero values for all three double parameters recalculates the spatial index with
// acceptable (but not necessarily optimal) values.
public void RebuildSpatialIndex(IFeatureClass featureClass, Double gridOneSize,
    Double gridTwoSize, Double gridThreeSize)
{
    // Get an enumerator for indexes based on the shape field.
    IIndexes indexes = featureClass.Indexes;
    String shapeFieldName = featureClass.ShapeFieldName;
    IEnumIndex enumIndex = indexes.FindIndexesByFieldName(shapeFieldName);
    enumIndex.Reset();

    // Get the index based on the shape field (should only be one) and delete it.
    IIndex index = enumIndex.Next();
    if (index != null)
    {
        featureClass.DeleteIndex(index);
    }

    // Clone the shape field from the feature class.
    int shapeFieldIndex = featureClass.FindField(shapeFieldName);
    IFields fields = featureClass.Fields;
    IField sourceField = fields.get_Field(shapeFieldIndex);
    IClone sourceFieldClone = (IClone)sourceField;
    IClone targetFieldClone = sourceFieldClone.Clone();
    IField targetField = (IField)targetFieldClone;

    // Open the geometry definition from the cloned field and modify it.
    IGeometryDef geometryDef = targetField.GeometryDef;
    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
    geometryDefEdit.GridCount_2 = 3;
    geometryDefEdit.set_GridSize(0, gridOneSize);
    geometryDefEdit.set_GridSize(1, gridTwoSize);
    geometryDefEdit.set_GridSize(2, gridThreeSize);

    // Create a spatial index and set the required attributes.
    IIndex newIndex = new IndexClass();
    IIndexEdit newIndexEdit = (IIndexEdit)newIndex;
    newIndexEdit.Name_2 = String.Concat(shapeFieldName, "_Index");
    newIndexEdit.IsAscending_2 = true;
    newIndexEdit.IsUnique_2 = false;

    // Create a fields collection and assign it to the new index.
    IFields newIndexFields = new FieldsClass();
    IFieldsEdit newIndexFieldsEdit = (IFieldsEdit)newIndexFields;
    newIndexFieldsEdit.AddField(targetField);
    newIndexEdit.Fields_2 = newIndexFields;

    // Add the spatial index back into the feature class.
    featureClass.AddIndex(newIndex);
}
[VB.NET]
' Passing zero values for all three double parameters recalculates the spatial index with
' acceptable (but not necessarily optimal) values.

Public Sub RebuildSpatialIndex(ByVal featureClass As IFeatureClass, ByVal gridOneSize As Double, ByVal gridTwoSize As Double, ByVal gridThreeSize As Double)
    
    ' Get an enumerator for indexes based on the shape field.
    Dim indexes As IIndexes = featureClass.Indexes
    Dim shapeFieldName As String = featureClass.ShapeFieldName
    Dim enumIndex As IEnumIndex = indexes.FindIndexesByFieldName(shapeFieldName)
    enumIndex.Reset()
    
    ' Get the index based on the shape field (should only be one) and delete it.
    Dim index As IIndex = enumIndex.Next()
    If Not index Is Nothing Then
        featureClass.DeleteIndex(index)
    End If
    
    ' Clone the shape field from the feature class.
    Dim shapeFieldIndex As Integer = featureClass.FindField(shapeFieldName)
    Dim fields As IFields = featureClass.Fields
    Dim sourceField As IField = fields.Field(shapeFieldIndex)
    Dim sourceFieldClone As IClone = CType(sourceField, IClone)
    Dim targetFieldClone As IClone = sourceFieldClone.Clone()
    Dim targetField As IField = CType(targetFieldClone, IField)
    
    ' Open the geometry definition from the cloned field and modify it.
    Dim geometryDef As IGeometryDef = targetField.GeometryDef
    Dim geometryDefEdit As IGeometryDefEdit = CType(geometryDef, IGeometryDefEdit)
    geometryDefEdit.GridCount_2 = 3
    geometryDefEdit.GridSize_2(0) = gridOneSize
    geometryDefEdit.GridSize_2(1) = gridTwoSize
    geometryDefEdit.GridSize_2(2) = gridThreeSize
    
    ' Create a spatial index and set the required attributes.
    Dim newIndex As IIndex = New IndexClass()
    Dim newIndexEdit As IIndexEdit = CType(newIndex, IIndexEdit)
    newIndexEdit.Name_2 = String.Concat(shapeFieldName, "_Index")
    newIndexEdit.IsAscending_2 = True
    newIndexEdit.IsUnique_2 = False
    
    ' Create a fields collection and assign it to the new index.
    Dim newIndexFields As IFields = New FieldsClass()
    Dim newIndexFieldsEdit As IFieldsEdit = CType(newIndexFields, IFieldsEdit)
    newIndexFieldsEdit.AddField(targetField)
    newIndexEdit.Fields_2 = newIndexFields
    
    ' Add the spatial index back into the feature class.
    featureClass.AddIndex(newIndex)
    
End Sub


See Also:

Creating fields
Working with indexes




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 for ArcGIS for Desktop, and the Geodatabase Update extension is required for 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