1. Composer install Elasticsearch
"elasticsearch/elasticsearch": "^8.15",
* Note: Elasticsearch clients have the same version as Elasticsearch (in this case version 8)
1. Add observer for model
#[ObservedBy([ViolationObserver::class])]
class Violation extends Model
observer code
<?php
namespace App\Observers;
use App\Models\Violation;
class ViolationObserver
{
public const VIOLATION_INDEX_NAME = 'violations_index';
protected $client;
public function __construct()
{
$this->client = app('elasticsearch');
}
/**
* Handle the Violation "created" event.
*/
public function created(Violation $model): void
{
$this->indexDocument($model);
}
/**
* Handle the Violation "updated" event.
*/
public function updated(Violation $model): void
{
$this->indexDocument($model);
}
/**
* Handle the Violation "deleted" event.
*/
public function deleted(Violation $model): void
{
$this->deleteDocument($model);
}
/**
* Handle the Violation "restored" event.
*/
public function restored(Violation $violation): void
{
//
}
/**
* Handle the Violation "force deleted" event.
*/
public function forceDeleted(Violation $violation): void
{
//
}
protected function indexDocument(Violation $model)
{
$params = [
'index' => self::VIOLATION_INDEX_NAME,
'id' => $model->id,
'body' => [
'id' => $model->id,
'control_plate' => $model->control_plate,
'status' => $model->status,
],
];
$this->client->index($params);
}
protected function deleteDocument(Violation $model)
{
$params = [
'index' => self::VIOLATION_INDEX_NAME,
'id' => $model->id,
];
$this->client->delete($params);
}
}
3. Register service
$this->app->singleton('elasticsearch', function ($app) {
return ClientBuilder::create()
->setHosts(config('elasticsearch.hosts'))
->build();
});
4. Create a command demo
<?php
namespace App\Console\Commands;
use App\Models\Violation;
use App\Observers\ViolationObserver;
use Illuminate\Console\Command;
class CreateAndSyncElasticsearchIndexForViolation extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'app:create-and-sync-elasticsearch-index-for-violation';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Command description';
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*/
public function handle()
{
$indexName = ViolationObserver::VIOLATION_INDEX_NAME;
$client = app('elasticsearch');
try {
// $this->createIndex($client, $indexName);
// $this->syncData($client, $indexName);
$this->searchData($client, $indexName);
} catch (\Exception $e) {
dump("Error: " . $e->getMessage());
}
$this->info('Index created and data synchronized successfully');
}
/*
* searchData
*/
protected function searchData($client, $indexName)
{
// Violation::create([
// 'control_plate' => '21'
// ]);
// Violation::destroy(9);
$params = [
'index' => $indexName, // Replace with your index name
'body' => [
'query' => [
// 'match_all' => new \stdClass() // Match all documents
// 'match' => [
// 'control_plate' => '11111111' // Replace with your field and search value
// ],
'wildcard' => [
'control_plate' => '*2*'
]
]
]
];
try {
$response = $client->search($params);
if (isset($response['hits']['hits'])) {
foreach ($response['hits']['hits'] as $hit) {
echo 'ID: ' . $hit['_id'] . '<br>';
echo 'Source: ' . print_r($hit['_source'], true) . '<br><br>';
}
} else {
echo 'No results found';
}
} catch (\Exception $e) {
echo 'Error: ', $e->getMessage();
}
}
/*
* createIndex
*/
protected function createIndex($client, $indexName)
{
$params = [
'index' => $indexName,
'body' => [
'mappings' => [
'properties' => [
'id' => [
'type' => 'integer'
],
'control_plate' => [
'type' => 'text'
],
'status' => [
'type' => 'keyword'
]
]
]
]
];
try {
$response = $client->indices()->create($params);
$this->info('Index created: ' . $indexName);
} catch (\Exception $e) {
$this->error('Error creating index: ' . $e->getMessage());
}
}
/*
* syncData
*/
protected function syncData($client, $indexName)
{
$models = Violation::all(); // Fetch all records from the table
$params = ['body' => []];
foreach ($models as $model) {
// Add index operation for each record
$params['body'][] = [
'index' => [
'_index' => $indexName,
'_id' => $model->id,
]
];
$params['body'][] = [
'id' => $model->id,
'control_plate' => $model->control_plate,
'status' => $model->status,
];
}
try {
// Bulk index the records
$response = $client->bulk($params);
$this->info('Data synchronized successfully');
} catch (\Exception $e) {
$this->error('Error synchronizing data: ' . $e->getMessage());
}
}
}
run command: php artisan app:create-and-sync-elasticsearch-index-for-violation
5. Docker-composer for Elasticsearch 8.15.1
### kibana815 ########################################
kibana815:
image: kibana:8.15.1
container_name: kibana
environment:
- ELASTICSEARCH_URL=http://elasticsearch815:9200
ports:
- "5601:5601"
networks:
- frontend
- backend
### ElasticSearch ########################################
elasticsearch815:
image: elasticsearch:8.15.1
container_name: elasticsearch
environment:
- discovery.type=single-node
- ES_JAVA_OPTS=-Xmx2g -Xms2g # Adjust JVM heap size as needed
- xpack.security.enabled=false # Disable security features
ports:
- "9200:9200" # HTTP port
- "9300:9300" # Transport port
volumes:
- elasticsearch815:/usr/share/elasticsearch/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9200"]
interval: 30s
retries: 3
start_period: 30s
timeout: 10s
networks:
- frontend
- backend
Thank you
No comments:
Post a Comment