<?php
// +----------------------------------------------------------------------
// | 访问官网:https://hawkhawk.club
// | author: hawk
// +----------------------------------------------------------------------
namespace hawk;
use Elasticsearch\ClientBuilder;
use think\facade\Log;
/**
* MySQL与 es 的参照对比
* mysql es
* 数据库(database) 索引(indices)
* 表(tables) 类型(types)
* 行(rows) 文档(documents)
* 字段(columns) 字段(fields)
* Class ElasticSearch
* @package app\common\controller
*/
class ElasticSearch
{
private $client;
private $host = [
'121.4.185.253:9200'
];
const INDEX = 'my_index';
public function __construct($host=[])
{
if($host)$this->host = $host;
$this->client = ClientBuilder::create()->setHosts($this->host)->build();
}
/**
* 创建索引
* 相当于数据库中建库建表的操作
* @param string $index
* @param array $body
* @return bool
*/
public function createIndex(string $index = 'my_index', array $body = []): bool
{
$params = [
'index' => $index, //索引名称
'body' => [
'settings' => [ // 设置配置
'number_of_shards' => 1, //主分片数
'number_of_replicas' => 0 //主分片的副本数
],
'mappings' => [ // 设置映射
'_source' => [ // 存储原始文档
'enabled' => 'true'
],
'properties' => $body // 配置数据结构与类型
],
]
];
try {
$this->client->indices()->create($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "创建索引{$index}失败");
return false;
}
return true;
}
/**
* 删除索引(删除数据库)
* @param string $index
* @return bool
*/
public function deleteIndex(string $index = self::INDEX): bool
{
$params = [
'index' => $index
];
try {
$this->client->indices()->delete($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "删除索引{$index}失败");
return false;
}
return true;
}
/**
* 判断索引是否存在
* @param string $index
* @return bool
*/
public function indexExists(string $index = self::INDEX): bool
{
$params = ['index' => $index];
return $this->client->indices()->exists($params);
}
/**
* 查看映射
* @param string $index
* @return array
*/
public function getMapping(string $index = self::INDEX): array
{
$params = [
'index' => $index,
];
try {
return $this->client->indices()->getMapping($params);
} catch (\Exception $e) {
return json_decode($e->getMessage(), true);
}
}
/**
* 添加文档(添加一行数据)
* @param int $id
* @param array $body
* @param string $index
* @return bool
*/
public function addDos(int $id, array $body, string $index = self::INDEX): bool
{
$params = [
'index' => $index,
'id' => $id,
'body' => $body
];
try {
$this->client->index($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "新增文档{$id}失败");
return false;
}
return true;
}
/**
* 批量插入文档
* @param array $params
* @return bool
*/
public function addAllDos(array $params)
{
try {
$this->client->bulk($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "分批插入失败");
return false;
}
return true;
}
/**
* 获取文档总数(统计)
* @param string $index
* @return array|mixed
*/
public function getCountDos(string $index = self::INDEX)
{
$params = [
'index' => $index,
];
try {
return $this->client->count($params);
} catch (\Exception $e) {
return json_decode($e->getMessage(), true);
}
}
/**
* 获取文档(获取一行数据)
* @param int $id
* @param string $index
* @return array|mixed
*/
public function getDoc(int $id, string $index = self::INDEX): array
{
$params = [
'index' => $index,
'id' => $id
];
try {
return $this->client->get($params);
} catch (\Exception $e) {
return json_decode($e->getMessage(), true);
}
}
/**
* 更新文档(更新一条数据)
* @param int $id
* @param array $body
* @param string $index
* @return bool
*/
public function updateDoc(int $id, array $body, string $index = self::INDEX): bool
{
$params = [
'index' => $index,
'id' => $id,
'body' => [
'doc' => $body
]
];
try {
$this->client->update($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "更新文档{$id}失败");
return false;
}
return true;
}
/**
* 删除文档(删除一条数据)
* @param int $id
* @param string $index
* @return bool
*/
public function deleteDoc(int $id, string $index = self::INDEX): bool
{
$params = [
'index' => $index,
'id' => $id
];
try {
$this->client->delete($params);
} catch (\Exception $e) {
Log::write($e->getMessage(), "删除文档{$id}失败");
return false;
}
return true;
}
/**
* 搜索
* @param string $keywords 检索词
* @param string $index 索引名
* @param int $limit 一次显示多少条
* @param int $page 分页页码,从几开始
* @return array
*/
public function searchDoc(string $keywords, string $index = self::INDEX, int $limit = 10, int $page = 1): array
{
$offset = ((int)$page - 1) * (int)$limit;
$params = [
'index' => $index,
'body' => [
'_source' => ['id', 'title'], // 指定返回的字段
'query' => [
// 联合查询
'bool' => [
'should' => [ // 相当于or
[
'match_phrase' => [
'title' => $keywords
]
],
[
'match_phrase' => [
'content' => $keywords
]
],
[
'match_phrase' => [
'keyword' => $keywords
]
],
],
],
],
'highlight' => [ // 搜索词高亮设置
// 'pre_tags' => "<p class='key' style='color: red;'>", // 自定义高亮样式
// 'post_tags' => "</p>",
'fields' => [ // 设置高亮的字段
'title' => (object)[],
'content' => (object)[],
'keyword' => (object)[],
]
],
// 'sort' => [['id' => ['order' => 'desc']]], // 排序,不设置会根据最高匹配度来排序
'from' => $offset, // 分页 - 从哪开始
'size' => $limit // 一次显示多少条
]
];
try {
return $this->client->search($params);
} catch (\Exception $e) {
return json_decode($e->getMessage(), true);
}
}
发表评论 取消回复