How to work with indexes


This document was published with and applies to ArcGIS 9.3.
A 10 version also exists. A 9.2 version also exists.
Summary This document contains general information regarding working with indexes in the geodatabase. Subjects covered include retrieving the collection of indexes from a table or feature class, and a specific index from a collection of indexes, adding or deleting a specific attribute index, and last, rebuilding a spatial index on a feature class.

Development licensing Deployment licensing
ArcView ArcView
ArcEditor ArcEditor
ArcInfo ArcInfo
Engine Developer Kit Engine Runtime

Additional Requirements
  • If working in ArcSDE, an ArcEditor or greater license is needed on ArcGIS Desktop, and the Geodatabase Update extension is required for ArcGIS Engine.

In this topic


Working with indexes


[Java]
static void displayIndexCount(ITable table)throws Exception
{
    IIndexes indexes = table.getIndexes();
    System.out.println("The table has an index count of " +
        indexes.getIndexCount());
}
 

Attribute indexes

Attribute indexes are based on an ordered list of one or more fields in a table. The order of the list determines which field is used first when resolving data queries. There is a limit of 10 fields in a geodatabase attribute index; a file geodatabase does not support multifield indexes.
 
For geodatabases, one attribute index is automatically created, this is the index on the ObjectID. You can also access indexes created in the native environment of the database management system (DBMS).
 
For shapefiles, both spatial and attribute indexes can be manipulated; however, note the usual limit of one field in an attribute index.
 
Index objects are not appropriate for use with INFO-based data such as coverages. The equivalent functionality is available from the IArcInfoTable interface.
The following code example accepts a class and checks its indexes to determine if they are spatial or based on the geodatabase ObjectID. If not, it prints the list of field names the index is associated with.
 

[Java]
// This method displays the fields associated with each of a class' indexes.
static void displayAttributeIndexFields(IFeatureClass featureClass)throws
    Exception
{
    // Get the collection of indexes.
    IIndexes indexes = featureClass.getIndexes();
    // Iterate through the indexes.
    for (int i = 0; i < indexes.getIndexCount(); i++)
    {
        // Get the fields collection and first field of the index.
        IIndex index = indexes.getIndex(i);
        IFields fields = index.getFields();
        IField field = fields.getField(0);
        // If the field isn't a shape field, display the index's name and its fields.
        if (field.getType() != esriFieldType.esriFieldTypeGeometry)
        {
            System.out.println("Index Name: " + index.getName());
            for (int j = 0; j < fields.getFieldCount(); j++)
            {
                field = fields.getField(j);
                System.out.println("Associated Field " + j + " : " +
                    field.getName());
            }
        }
    }
}

[Java]
public void addIndexToFeatureClass(IFeatureClass featureClass, String indexName,
    String nameOfField)throws Exception
{
    // Make sure the feature class contains the specified field.
    int fieldIndex = featureClass.findField(nameOfField);
    if (fieldIndex ==  - 1)
    {
        throw new Exception(
            "The specified field does not exist in the feature class.");
    }
    // Get the specified field from the feature class.
    IFields featureClassFields = featureClass.getFields();
    IField field = featureClassFields.getField(fieldIndex);
    // Create a new fields collection and add the specified field to it.
    IFields fields = new Fields();
    IFieldsEdit fieldsEdit = (IFieldsEdit)fields;
    fieldsEdit.setFieldCount(1);
    fieldsEdit.setFieldByRef(0, field);
    //Create a new index and cast to the IIndexEdit interface.
    IIndex index = new Index();
    IIndexEdit indexEdit = (IIndexEdit)index;
    // Set the index's properties, including the fields it will have associated with it.
    indexEdit.setFieldsByRef(fields);
    indexEdit.setIsAscending(false);
    indexEdit.setIsUnique(false);
    indexEdit.setName(indexName);
    // Attempt to acquire an exclusive schema lock on the feature class.
    ISchemaLock schemaLock = (ISchemaLock)featureClass;
    schemaLock.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
    featureClass.addIndex(index);
    schemaLock.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}
The IIndexes.FindIndexesByFieldName method can be used to find all the indexes with a specific field associated with them. The following code example shows how to delete all of the indexes from a feature class given a specific field:
 

[Java]
static void deleteIndexesByFieldName(IFeatureClass featureClass, String
    nameOfField)throws Exception
{
    // Find all of the indexes associated with a specific field.
    IIndexes indexes = featureClass.getIndexes();
    IEnumIndex enumIndex = indexes.findIndexesByFieldName(nameOfField);
    // Attempt to acquire an exclusive schema lock on the feature class.
    ISchemaLock schemaLock = (ISchemaLock)featureClass;
    schemaLock.changeSchemaLock(esriSchemaLock.esriExclusiveSchemaLock);
    // Iterate through and delete the returned indexes.
    IIndex index = null;
    while ((index = enumIndex.next()) != null)
    {
        featureClass.deleteIndex(index);
    }
    schemaLock.changeSchemaLock(esriSchemaLock.esriSharedSchemaLock);
}
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.

[Java]
static IIndex getIndexByName(IIndexes indexes, String indexName)throws Exception
{
    int[] indexPosition = 
    {
         - 1
    };
    indexes.findIndex(indexName, indexPosition);
    IIndex index = indexes.getIndex(indexPosition[0]);
    return index;
}

Spatial indexes

Spatial indexes exist on the Shape field of a feature class. Some of the spatial index parameters—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, so you don't have to create the spatial index with ArcObjects.
 
It is possible to delete and re-create the spatial index with the IFeatureClass.DeleteIndex and IFeatureClass.AddIndex methods.  This is done by deleting an existing spatial index, cloning the feature class' shape field and modifying its geometry definition, and creating a new spatial index with the cloned field.  The following code example shows how to do this:
It is not possible to re-create the spatial index on a feature class in a personal geodatabase.

[Java]
// Passing zero values for all three double parameters will recalculate the spatial index with
// acceptable (but not necessarily optimal) values.
static void rebuildSpatialIndex(IFeatureClass featureClass, double gridOneSize,
    double gridTwoSize, double gridThreeSize)throws Exception
{
    // Get an enumerator for indexes based on the shape field.
    IIndexes indexes = featureClass.getIndexes();
    String shapeFieldName = featureClass.getShapeFieldName();
    IEnumIndex enumIndex = indexes.findIndexesByFieldName(shapeFieldName);
    enumIndex.reset();
    // Get the index based on the shape field (should only be one), 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.getFields();
    IField sourceField = fields.getField(shapeFieldIndex);
    IClone sourceFieldClone = (IClone)sourceField;
    IClone targetFieldClone = sourceFieldClone.esri_clone();
    IField targetField = (IField)targetFieldClone;
    // Open the geometry definition from the cloned field and modify it.
    IGeometryDef geometryDef = targetField.getGeometryDef();
    IGeometryDefEdit geometryDefEdit = (IGeometryDefEdit)geometryDef;
    geometryDefEdit.setGridCount(3);
    geometryDefEdit.setGridSize(0, gridOneSize);
    geometryDefEdit.setGridSize(1, gridTwoSize);
    geometryDefEdit.setGridSize(2, gridThreeSize);
    // Create a new spatial index and set the required attributes.
    IIndex newIndex = new Index();
    IIndexEdit newIndexEdit = (IIndexEdit)newIndex;
    newIndexEdit.setName(shapeFieldName + "_Index");
    newIndexEdit.setIsAscending(true);
    newIndexEdit.setIsUnique(false);
    // Create a fields collection and assign it to the new index.
    IFields newIndexFields = new Fields();
    IFieldsEdit newIndexFieldsEdit = (IFieldsEdit)newIndexFields;
    newIndexFieldsEdit.addField(targetField);
    newIndexEdit.setFieldsByRef(newIndexFields);
    // Add the spatial index back into the feature class.
    featureClass.addIndex(newIndex);
}


See Also:

How to work with fields
How to create new fields