If you need to improve the performance of your application by moving search queries to Elasticsearch or implement more advanced searching, OriginPHP makes it ultra simple to implement Elasticsearch in your web application.
To install this plugin
$ composer require originphp/elasticsearch
To use the Elasticsearch features you will need to install Elasticsearch 7.0 or greater. At the bottom of this text there is information how to do this with Docker.
Here I will cover the configuration of Elasticsearch, the installation instructions for Elasticsearch with Docker are at the bottom of this guide.
First you need to configure the Elasticsearch connection. In your configuration file config/application.php
add the following (or create a separate file and adjust the bootstrap);
use Origin\Elasticsearch\Elasticsearch;
Elasticsearch::config('default', [
'host' => 'elasticsearch', // or 127.0.0.1 if not using the docker version
'port' => 9200,
'timeout' => 400,
'https' => false
]);
Add the Elasticsearch Concern
to your Model
.
use Elasticsearch\Model\Concern\ElasticSearch;
class MyModel extends ApplicationModel
{
use ElasticSearch;
}
If you want to use a different connection, then you will need to set the elasticSearchConnection
property on in your Model
.
protected $elasticSearchConnection = 'some-other-connection';
Whenever you create or delete a record the Elasticsearch index will be updated in the background, providing you do not disable callbacks.
The
Model::updateAll
andModel::deleteAll
do not trigger callbacks and therefore wont update or delete records from the index. You should loop through each record and update or delete so that the index can be kept in sync.
To carry out a search use the model, which will have new methods from the Concern
.
To search using keywords or a query string on columns in your index
$results = $this->Post->search('Top Frameworks 2019');
$results = $this->Post->search('"Top Frameworks 2019"');
$results = $this->Post->search('title:how to');
$results = $this->Post->search('+framework +php -draft');
If you want to carry out a custom search using Elasticsearch query DSL (Domain Specific Language), you can do like this
$query = [
'query' => [
'multi_match' => [
'query' => 'php framework',
'fields' => ['title','body']
]
]
];
$results = $this->Post->search($query);
If you want to customize the search function or use custom searches from within your model you can do it like this:
public function searchTitleAndBody(string $query)
{
return $this->search([
'query' => [
'multi_match' => [
'query' => $query,
'fields' => ['title','body']
]
]
]);
}
By default, OriginPHP dynamically maps each column to Elasticsearch, all columns for the Model
will be stored in the index unless you tell it otherwise.
To manually map columns for the indexes, in your model call the index method for each column that you want to index. You can optionally pass an options array which takes settings from Elasticsearch mapping types.
use Elasticsearch\Model\Concern\ElasticSearch;
class Article extends ApplicationModel
{
use Elasticsearch;
protected function initialize(array $config) : void
{
// Set the columns to index
$this->index('title',['type'=>'keyword','analyzer'=>'english']);
$this->index('body'); // this will dynamically map
// To set index settings
$this->indexSettings(['number_of_shards' => 1]);
}
}
You will then need to run the elasticsearch:reindex
command telling which models recreate the indexes on with new settings, the data will then be added back to the new indexes.
$ bin/console elasticsearch:reindex Post Comment
The only time indexes are created with your settings is when this command is run, if not Elasticsearch creates the index if it does not exist with default settings.
Add the following to your docker-compose.yml
file.
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:7.3.0
container_name: elasticsearch
environment:
- discovery.type=single-node
volumes:
- es-data:/usr/share/elasticsearch/data
ports:
- 9200:9200
And under the volumes:
node add
es-data:
driver: local
The next time you run docker-compose up
the Elasticsearch container will created.
For information on how to install on Ubuntu server see this article.
When testing your application (or this plugin) you will need to start an Elasticsearch instance, you can do this with a nice oneliner from the command line
$ docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:7.3.0