SoFunction
Updated on 2025-03-06

Explanation of the latest examples of using ElasticSearch in PHP

Many examples about ES on the Internet are outdated and the version is very old. The test environment of this article is ES6.5

Installation via composer

composer require 'elasticsearch/elasticsearch'

Introduced in code

require 'vendor/';

use Elasticsearch\ClientBuilder;

$client = ClientBuilder::create()->setHosts(['172.16.55.53'])->build();

The following is a simple addition and search function step by step.

First, create a new index:

Index corresponds to the database in relational data (hereinafter referred to as MySQL), rather than the index in MySQL. This should be clear

$params = [
  'index' => 'myindex', #index's name cannot start with capital and underscore  'body' => [
    'settings' => [
      'number_of_shards' => 2,
      'number_of_replicas' => 0
    ]
  ]
];
$client->indices()->create($params);

In MySQL, just having a database is not enough, and you still need to create tables. The same is true for ES. The type in ES corresponds to the tables in MySQL.

Note: Before ES6, an index had multiple types, just as natural as a database in MySQL had multiple tables, but after ES6, each index only allowed one type, and the type may be cancelled in future versions.

Type is not defined separately, but is defined together with fields

$params = [
  'index' => 'myindex',
  'type' => 'mytype',
  'body' => [
    'mytype' => [
      '_source' => [
        'enabled' => true
      ],
      'properties' => [
        'id' => [
          'type' => 'integer'
        ],
        'first_name' => [
          'type' => 'text',
          'analyzer' => 'ik_max_word'
        ],
        'last_name' => [
          'type' => 'text',
          'analyzer' => 'ik_max_word'
        ],
        'age' => [
          'type' => 'integer'
        ]
      ]
    ]
  ]
];
$client->indices()->putMapping($params);

When defining fields, it can be seen that each field can define a separate type, and the word segmenter ik is also customized in first_name.

This word segmenter is a plug-in that needs to be installed separately. Please refer to another article:ElasticSearch basic attempt

Now there are databases and tables, you can insert data into them

Concept: The data here is called document in ES

$params = [
  'index' => 'myindex',
  'type' => 'mytype',
  //'id' => 1, #You can specify the id manually or you can not specify random generation  'body' => [
    'first_name' => 'open',
    'last_name' => 'three',
    'age' => 35
  ]
];
$client->index($params);

Insert a little more data and then see how to extract the data:

Take out a single piece of data by id:

Interlude: If you did not pass in the id when adding the document before, ES will randomly generate an id. How to check it through the id at this time? I don't know what the id is.

So this inserts a simple search, the simplest, no search criteria, and returns all documents under all indexes:

$data = $client->search();

You can now look for the id, but you will find that the id may look like this: zU65WWgBVD80YaV8iVMk, don't be surprised, this is randomly generated by ES.

Now you can find the specified document by id:

$params = [
  'index' => 'myindex',
  'type' => 'mytype',
  'id' =>'zU65WWgBVD80YaV8iVMk'
];
$data = $client->get($params);

The last slightly troublesome feature:

Note: I don’t plan to explain this example in detail here, it doesn’t matter if I don’t understand it. The main purpose of this article is the basic usage and does not involve the essence of ES.

The essence of ES lies in searching. I will continue to analyze the following articles in depth.

$query = [
  'query' => [
    'bool' => [
      'must' => [
        'match' => [
          'first_name' => 'open',
        ]
      ],
      'filter' => [
        'range' => [
          'age' => ['gt' => 76]
        ]
      ]
    ]

  ]
];
$params = [
  'index' => 'myindex',
// 'index' => 'm*', #index and type can be fuzzyly matched, and even these two parameters are optional  'type' => 'mytype',
  '_source' => ['first_name','age'], // Request the specified field  'body' => array_merge([
    'from' => 0,
    'size' => 5
  ],$query)
];
$data = $this->EsClient->search($params);

The above is a simple usage process, but it is not complete enough. It only talks about adding documents, but does not talk about how to delete documents.

Below I posted the complete test code, based on the Laravel environment. Of course, the environment only affects operation, not understanding, and includes basic common operations:

<?php
use Elasticsearch\ClientBuilder;
use Faker\Generator as Faker;
/**
 * ES's php test code
 */
class EsDemo {
	private $EsClient = null;
	private $faker = null;
	/**
 * To simplify the test, this test only operates one Index and one Type by default.
 * So here is fixed as megacorp and employee
 */
	private $index = 'megacorp';
	private $type = 'employee';
	public function __construct(Faker $faker) {
		/**
 * Instantiate the ES client
 */
		$this->EsClient = ClientBuilder::create()->setHosts(['172.16.55.53'])->build();
		/**
 * This is a data generation library, and you can refer to the network for details.
 */
		$this->faker = $faker;
	}
	/**
 * Bulk document generation
 * @param $num
 */
	public function generateDoc($num = 100) {
		foreach (range(1,$num) as $item) {
			$this->putDoc([
			'first_name' => $this->faker->name,
			'last_name' => $this->faker->name,
			'age' => $this->faker->numberBetween(20,80)
			]);
		}
	}
	/**
 * Delete a document
 * @param $id
 * @return array
 */
	public function delDoc($id) {
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		'id' =>$id
		];
		return $this->EsClient->delete($params);
	}
	/**
 * Search for documents, query is the query condition
 * @param array $query
 * @param int $from
 * @param int $size
 * @return array
 */
	public function search($query = [], $from = 0, $size = 5) {
		// $query = [
		// 'query' => [
		// 'bool' => [
		// 'must' => [
		// 'match' => [
		// 'first_name' => 'Cronin',
		// ]
		// ],
		// 'filter' => [
		// 'range' => [
		// 'age' => ['gt' => 76]
		// ]
		// ]
		// ]
		//
		// ]
		// ];
		$params = [
		'index' => $this->index,
		// 'index' => 'm*', #index and type can be fuzzyly matched, and even these two parameters are optional		'type' => $this->type,
		'_source' => ['first_name','age'], // Request the specified field		'body' => array_merge([
		'from' => $from,
		'size' => $size
		],$query)
		];
		return $this->EsClient->search($params);
	}
	/**
 * Get multiple documents at once
 * @param $ids
 * @return array
 */
	public function getDocs($ids) {
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		'body' => ['ids' => $ids]
		];
		return $this->EsClient->mget($params);
	}
	/**
 * Get a single document
 * @param $id
 * @return array
 */
	public function getDoc($id) {
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		'id' =>$id
		];
		return $this->EsClient->get($params);
	}
	/**
 * Update a document
 * @param $id
 * @return array
 */
	public function updateDoc($id) {
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		'id' =>$id,
		'body' => [
		'doc' => [
		'first_name' => 'open',
		'last_name' => 'three',
		'age' => 99
		]
		]
		];
		return $this->EsClient->update($params);
	}
	/**
 * Add a document to Index Type
 * @param array $body
 * @return void
 */
	public function putDoc($body = []) {
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		// 'id' => 1, #You can specify the id manually or you can not specify random generation		'body' => $body
		];
		$this->EsClient->index($params);
	}
	/**
 * Delete all Indexes
 */
	public function delAllIndex() {
		$indexList = $this->esStatus()['indices'];
		foreach ($indexList as $item => $index) {
			$this->delIndex();
		}
	}
	/**
 * Get the status information of ES, including the index list
 * @return array
 */
	public function esStatus() {
		return $this->EsClient->indices()->stats();
	}
	/**
 * Create an index Index (the index in non-relational database, but the database in relational data)
 * @return void
 */
	public function createIndex() {
		$this->delIndex();
		$params = [
		'index' => $this->index,
		'body' => [
		'settings' => [
		'number_of_shards' => 2,
		'number_of_replicas' => 0
		]
		]
		];
		$this->EsClient->indices()->create($params);
	}
	/**
 * Check if the Index exists
 * @return bool
 */
	public function checkIndexExists() {
		$params = [
		'index' => $this->index
		];
		return $this->EsClient->indices()->exists($params);
	}
	/**
 * Delete an Index
 * @return void
 */
	public function delIndex() {
		$params = [
		'index' => $this->index
		];
		if ($this->checkIndexExists()) {
			$this->EsClient->indices()->delete($params);
		}
	}
	/**
 * Get Index's document template information
 * @return array
 */
	public function getMapping() {
		$params = [
		'index' => $this->index
		];
		return $this->EsClient->indices()->getMapping($params);
	}
	/**
 * Create a document template
 * @return void
 */
	public function createMapping() {
		$this->createIndex();
		$params = [
		'index' => $this->index,
		'type' => $this->type,
		'body' => [
		$this->type => [
		'_source' => [
		'enabled' => true
		],
		'properties' => [
		'id' => [
		'type' => 'integer'
		],
		'first_name' => [
		'type' => 'text',
		'analyzer' => 'ik_max_word'
		],
		'last_name' => [
		'type' => 'text',
		'analyzer' => 'ik_max_word'
		],
		'age' => [
		'type' => 'integer'
		]
		]
		]
		]
		];
		$this->EsClient->indices()->putMapping($params);
		$this->generateDoc();
	}
}

This is the article about the latest examples of using ElasticSearch in PHP. For more information about using ElasticSearch in PHP, please search for my previous articles or continue browsing the related articles below. I hope you will support me in the future!