Re-indexing Process
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
Step 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
});
Step 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();
Step 3: Delete the Original Index
Once you've confirmed that all data has been successfully copied, delete the original index.
Schema::delete('site_logs');
Step 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');