PHP code example of phoenix-lib / elasticsearch-model

1. Go to this page and download the library: Download phoenix-lib/elasticsearch-model library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

phoenix-lib / elasticsearch-model example snippets


Schema::create('articles', function (Blueprint $table) {
    $table->increments('id');
    $table->string('title');
});

class Article extends Eloquent
{
}

Article::create([ 'title' => 'Quick brown fox' ]);
Article::create([ 'title' => 'Fast black dogs' ]);
Article::create([ 'title' => 'Swift green frogs' ]);

use Datashaman\Elasticsearch\Model\ElasticsearchModel;

class Article extends Eloquent
{
    use ElasticsearchModel;
    protected static $elasticsearch;
}

Article::elasticsearch()->client()->cluster()->health();
=> [ "cluster_name" => "elasticsearch", "status" => "yellow", ... ]

Article::elasticsearch()->client(ClientBuilder::fromConfig([ 'hosts' => [ 'api.server.org' ] ]));

Article::elasticsearch()->import([ 'force' => true ]);

$response = Article::search('fox dogs');

$response->took();
=> 3

$response->total();
=> 2

$response[0]->_score;
=> 0.02250402

$response[0]->title;
=> "Fast black dogs"

$response->results()
    ->map(function ($r) { return $r->title; })
    ->all();
=> ["Fast black dogs", "Quick brown fox"]

$response->getCollection()
    ->map(function ($r) { return $r->title; })
    ->all();
=> ["Fast black dogs", "Quick brown fox"]

$response->filter(function ($r) { return preg_match('/^Q/', $r->title); })
    ->map(function ($r) { return $r->title; })
    ->all();
=> ["Quick brown fox"]

$response->records()
    ->map(function ($article) { return $article->title; })
    ->all();
=> ["Fast black dogs", "Quick brown fox"]

$lines = [];
$response->records()->eachWithHit(function ($record, $hit) {
    $lines[] = "* {$record->title}: {$hit->_score}";
});

$lines;
=> [ "* Fast black dogs: 0.01125201", "* Quick brown fox: 0.01125201" ]

$lines = $response->records()->mapWithHit(function ($record, $hit) {
    return "* {$record->title}: {$hit->_score}";
})->all();

$lines;
=> [ "* Fast black dogs: 0.01125201", "* Quick brown fox: 0.01125201" ]

$response
    ->records([], function ($query) {
        $query->orderBy('title', 'desc');
    })
    ->map(function ($article) { return $article->title; })
    ->all();

=> [ 'Quick brown fox', 'Fast black dogs' ]

# Delegates to the results on page 2 with 20 per page
$response->perPage(20)->page(2);

# Records on page 2 with 20 per page; records ordered the same as results
# Order of the `page` and `perPage` calls doesn't matter
$response->page(2)->perPage(20)->records();

# Results on page 2 with (default) 15 results per page
$response->page(2)->results();

# Records on (default) page 1 with 10 records per page
$response->perPage(10)->records();

$response->page(2)->results();
=> object(Illuminate\Pagination\LengthAwarePaginator) ...

$results = response->page(2);

$results->setPath('/articles');
$results->render();
=> <ul class="pagination">
    <li><a href="/articles?page=1" rel="prev">&laquo;</a></li>
    <li><a href="/articles?page=1">1</a></li>
    <li class="active"><span>2</span></li>
    <li><a href="/articles?page=3">3</a></li>
    <li><a href="/articles?page=3" rel="next">&raquo;</a></li>
</ul>

Article::settings(['index' => ['number_of_shards' => 1]], function ($s) {
    $s['index'] = array_merge($s['index'], [
        'number_of_replicas' => 4,
    ]);
});

Article::settings->toArray();
=> [ 'index' => [ 'number_of_shards' => 1, 'number_of_replicas' => 4 ] ]

Article::mappings(['dynamic' => false], function ($m) {
    $m->indexes('title', [
        'analyzer' => 'english',
        'index_options' => 'offsets'
    ]);
});

Article::mappings()->toArray();
=> [ "article" => [
    "dynamic" => false,
    "properties" => [
        "title" => [
            "analyzer" => "english",
            "index_options" => "offsets",
            "type" => "string",
        ]
    ]
]]

Article::elasticsearch()->client()->indices()->delete(['index' => Article::indexName()]);
Article::elasticsearch()->client()->indices()->create([
    'index' => Article::indexName(),
    'body' => [
        'settings' => Article::settings()->toArray(),
        'mappings' => Article::mappings()->toArray(),
    ],
]);

Article::elasticsearch()->createIndex(['force' => true]);
Article::elasticsearch()->refreshIndex();

class Article {
    protected static $indexName = 'article-production';
    protected static $documentType = 'post';
}

Article::indexName('article-production');
Article::documentType('post');

Article::first()->indexDocument();
=> [ 'ok' => true, ... "_version" => 2 ]

Note that this implementation differs from the Ruby one, where the instance has an elasticsearch() method and proxy object. In this package, the instance methods are added directly to the model. Implementing the same pattern in PHP is not easy to do cleanly.

### Automatic callbacks

You can auomatically update the index whenever the record changes, by using the `Datashaman\\Elasticsearch\\Model\\Callbacks` trait in your model:


Article::saved(function ($article) {
    $result = $article->indexDocument();
    Log::debug("Saved document", compact('result'));
});

Article::deleted(function ($article) {
    $result = $article->deleteDocument();
    Log::debug("Deleted document", compact('result'));
});

Article::saved(function ($article) {
    Queue::pushOn('default', new Indexer('index', Article::class, $article->id));
});

class Indexer implements SelfHandling, ShouldQueue
{
    use InteractsWithQueue, SerializesModels;

    public function __construct($operation, $class, $id)
    {
        $this->operation = $operation;
        $this->class = $class;
        $this->id = $id;
    }

    public function handle()
    {
        $class = $this->class;

        switch ($this->operation) {
        case 'index':
            $record = $class::find($this->id);
            $class::elasticsearch()->client()->index([
                'index' => $class::indexName(),
                'type' => $class::documentType(),
                'id' => $record->id,
                'body' => $record->toIndexedArray(),
            ]);
            $record->indexDocument();
            break;
        case 'delete':
            $class::elasticsearch()->client()->delete([
                'index' => $class::indexName(),
                'type' => $class::documentType(),
                'id' => $this->id,
            ]);
            break;
        default:
            throw new Exception('Unknown operation: '.$this->operation);
        }
    }
}

Article::first()->toIndexedArray();
=> [ 'title' => 'Quick brown fox' ]

class Article
{
    use ElasticsearchModel;

    public function toIndexedArray($options = null)
    {
        return $this->toArray();
    }
}