Skip to content

Re-indexing Process

This content is for v3.9. Switch to the latest version for up-to-date documentation.

Re-indexing in Elasticsearch is a critical operation, especially when you need to alter the mapping of existing data. This process involves creating a new index with the desired mappings and copying the data from the old index to the new one. Here’s a step-by-step example of how this can be achieved using the schema functionality of this plugin.

Missed Mapping

To create a real-world scenario, let’s consider a site log system that stores the URL, user IP, and location of visitors.

We’ll intentionally overlook the mapping of the location field, which should be mapped as a geo_point type.

Schema::create('site_logs', function (IndexBlueprint $index) {
$index->keyword('url');
$index->ip('user_ip');
// Initially, the 'location' field might be overlooked or incorrectly mapped
});

Assuming there’s a model for this index, you create a record like so:

SiteLog::create([
'url' => 'https://example.com/contact-us',
'user_ip' => '0.0.0.0',
'location' => ['lat' => -7.3, 'lon' => 3.1] // This field is not correctly mapped yet
]);

After some time, you realize that the location field should be mapped as a geo_point type. If you try to filter records based on the location field, you’ll get an error because the field is not correctly mapped.


Re-indexing

  1. Create a Temporary Index with Correct Mapping

    Create a temporary index with the correct mapping for the location field.

    Schema::create('temp_site_logs', function (IndexBlueprint $index) {
    $index->keyword('url');
    $index->ip('user_ip');
    $index->geo('location'); // Correct mapping for the 'location' field
    });
  2. Re-indexing Data to the Temporary Index

    Copy all records from the original site_logs index to the temp_site_logs index.

    $result = Schema::reIndex('site_logs', 'temp_site_logs');

    NB: Verify the success of the re-indexing operation, analyze $result->data for any errors and make sure all the collections were copied to the new index.

    $copiedRecords = DB::connection('elasticsearch')->table('my_prefix_temp_site_logs')->count();
  3. Delete the Original Index

    Once you’ve confirmed that all data has been successfully copied, delete the original index.

    Schema::delete('site_logs');
  4. Recreating the Original Index with Correct Mapping

    Now, recreate the site_logs index with the correct mappings.

    Schema::create('site_logs', function (IndexBlueprint $index) {
    $index->keyword('url');
    $index->ip('user_ip');
    $index->geo('location'); // Now with the correct mapping
    });
  5. Re-indexing Data Back to the Original Index

    Copy the data from the temporary index back to the original index.

    $result = Schema::reIndex('temp_site_logs', 'site_logs');

    Again, verify the success of the re-indexing operation:

    $copiedRecords = DB::connection('elasticsearch')->table('my_prefix_site_logs')->count();
  6. Verifying the Correct Functionality

    Now, with the location field correctly mapped, filtering operations should work as expected.

    $logs = SiteLog::filterGeoBox('location', [-10, 10], [10, -10])->get();

    If there is an issue then delete the index and go back to step 4

  7. Delete the Temporary Index

    Finally, delete the temporary index.

    Schema::delete('temp_site_logs');