安装扩展
composer require elasticsearch/elasticsearch 7.15
操作ES客户端类
<?php
namespace app\index;
use Elasticsearch\ClientBuilder;
class EsService
{
private $client;
public function __construct()
{
$params = [
'host' => '127.0.0.1',
'port' => '9200',
// 'scheme' => 'http',
'user' => 'es',
'pass' => 'es'
];
$this->client = ClientBuilder::create()->setHosts($params)->setConnectionPool('\Elasticsearch\ConnectionPool\SimpleConnectionPool', [])
->setRetries(10)->build();
}
/**
* @param string $index_name
* @return array
* 创建索引
*/
public function create_index(string $index_name = 'es_test')
{ // 只能创建一次哦
$params = [
'index' => $index_name,
'body' => [
'settings' => [
'number_of_shards' => 15,
'number_of_replicas' => 1
]
],
];
return $this->client->indices()->create($params);
}
/**
* @param string $index_name
* @return array
* 删除索引
*/
public function delete_index(string $index_name = 'es_test')
{
$params = ['index' => $index_name];
$response = $this->client->indices()->delete($params);
return $response;
}
/**
* @param string $type_name
* @param string $index_name
* @return array
* 创建文档模板
*/
public function create_mapping(string $type_name = 'es_test_type', string $index_name = 'es_test')
{
$params = [
'index' => $index_name,//这里是索引名,相当于数据库名
'type' => $type_name,//这里是类型名,相当于表名
'include_type_name' => true,
'body' => [
//下面是数据类型定义,相当于数据库字段
'properties' => [
'id' => [
'type' => 'byte', // 整型
'index' => 'false', // 非全文搜索
],
'name' => [
'type' => 'text', // 字符串型
'index' => 'true', // 全文搜索
],
'desc' => [
'type' => 'text', // 字符串型
'index' => 'true', // 全文搜索
],
'age' => [
'type' => 'integer',
'index' => 'false', //非 全文搜索
],
]
]
];
return $this->client->indices()->putMapping($params);
}
/**
* @param string $keywords
* @param string $index_name
* @param string $type_name
* @param int $from
* @param int $size
* @return array|callable
* 查询文档 (分页,排序,权重,过滤)
*/
public function search_doc(string $keywords = "跑啊", string $index_name = "es_test", $type_name = "es_test_type", $from = 0, $size = 10)
{
$params = [
'index' => $index_name,
'type' => $type_name,
'body' => [
'query' => [
'bool' => [
//bool查询,可以把很多小的查询组成一个更为复杂的查询,
'should' => [
// 这里should是查询desc字段包含$keywords关键词或者name字段包含$keywords关键词的文档。
//可以改为"must"意思是同时包含。must_not排除包含
['match' =>
[
'desc' =>
[
'query' => $keywords,
'boost' => 3, // 权重大
]
]
],
['match' =>
['name' =>
[
'query' => $keywords,
'boost' => 2,
]
]
],
],
],
],
'sort' =>
[
'age' => ['order' => 'desc']
]
, 'from' => $from, 'size' => $size
]
];
return $this->client->search($params);
}
/**
* @param string $type_name
* @param string $index_name
* @return array
* 查看映射
*/
public function get_mapping(string $type_name = 'es_test_type', string $index_name = 'es_test')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'include_type_name' => true,
];
return $this->client->indices()->getMapping($params);
}
/**
* @param $id
* @param array $doc
* @param string $index_name
* @param string $type_name
* @return array|callable
* 添加单个文档
*/
public function add_single_doc($id, array $doc, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'id' => $id,
'body' => $doc
];
return $this->client->index($params);
}
/**
* @param $body
* @param string $index_name
* @param string $type_name
* @return array
* 批量添加文档
*/
public function add_bulk_doc(array $body, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'body' => $body
];
return $this->client->bulk($params);
}
/**
* @param $id
* @param string $index_name
* @param string $type_name
* @return bool
* 判断文档存在
*/
public function exists_doc($id, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'id' => $id
];
return $this->client->exists($params);
}
/**
* @param $id
* @param string $index_name
* @param string $type_name
* @return array|callable
* 获取文档
*/
public function get_doc($id, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'id' => $id
];
return $this->client->get($params);
}
/**
* @param $id
* @param array $arr
* @param string $index_name
* @param string $type_name
* @return array|callable
* 更新文档
*/
public function update_doc($id, array $arr, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
// 可以灵活添加新字段,最好不要乱添加
$params = [
'index' => $index_name,
'type' => $type_name,
'id' => $id,
'body' => [
'doc' => $arr //['name'=>'ssss','age'=>56]
]
];
return $this->client->update($params);
}
/**
* @param $id
* @param string $index_name
* @param string $type_name
* @return array|callable
* 删除文档
*/
public function delete_doc($id, string $index_name = 'es_test', string $type_name = 'es_test_type')
{
$params = [
'index' => $index_name,
'type' => $type_name,
'id' => $id
];
return $this->client->delete($params);
}
protected function __clone()
{
// TODO: Implement __call() method.
}
}
ES类使用
public function index()
{
$EsService=new EsService();
//创建索引
$EsService->create_index();
//创建文档模板
$EsService->create_mapping();
//单个添加
$data = [];
$data[] = ['id' => 1, 'name' => 'php', 'desc' => '世界上最强的语言。', 'age' => 23];
$data[] = ['id' => 2, 'name' => 'laravel', 'desc' => '优雅的框架。', 'age' => 24];
$data[] = ['id' => 3, 'name' => 'java', 'desc' => '牛逼后端语言', 'age' => 29];
foreach ($data as $k=>$v){
//添加文档
$EsService->add_single_doc($v['id'],$v);
}
//批量添加
$arr=[];
for ($i=0;$i<100;$i++){
$arr[]=[
'id'=>$i+1,
'name'=>'name_'.mt_rand(1,9222),
'desc'=>'desc_'.mt_rand(8787,922102),
'age'=>mt_rand(8,100)
];
}
$body=[];
foreach ($arr as $k=>$v){
$body[($k*2)] = ['index' => [ '_id' => $v['id'].'_'.$v['age'],'_type'=>'es_test_type','_index'=>'es_test']];
$body[(($k*2)+1)] = $v;
}
$EsService->add_bulk_doc($body);
//搜索
$result=$EsService->search_doc('php');
dump($result);
}