<?php
namespace ZincSearch;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Http\Message\ResponseInterface;
class ZincSearchService
{
protected $client;
public static function build()
{
return new self();
}
public function __construct()
{
$this->client = new Client([
'auth' => [
'admin',
'123456',
],
'base_uri' => 'http://127.0.0.1:4080',
'timeout' => 3
]);
$this->projectName = 'jiuyu_'; // 索引名(项目名)
}
/**
* 处理json数据
* @param ResponseInterface $resp
* @return mixed
* @throws Exception
*/
public function handleJson(ResponseInterface $resp)
{
if ($resp->getStatusCode() !== 200) {
throw new Exception('请求失败,失败原因:' . $resp->getBody(), $resp->getStatusCode());
}
$body = $resp->getBody();
return json_decode($body, true);
}
/**
* 获取zincSearch版本
* @return mixed
* @throws GuzzleException
* @throws Exception
*/
public function version()
{
$resp = $this->client->get('/version');
return $this->handleJson($resp);
}
/**
* 批量新增或者批量更新
* @param $index string 索引
* @param $primaryKey string 主键
* @param $data array 数据
* @return mixed
* @throws GuzzleException
* @throws Exception
*/
public function bulk($index, $primaryKey, array $data)
{
$params = [];
$key = 0;
$indexName = $this->projectName . $index;
foreach ($data as $v) {
$params[$key]['index'] = [
'_index' => $indexName,
'_id' => strval($v[$primaryKey]),
];
$key++;
$params[$key] = $v;
$key++;
}
// 把数组转化成ndjson
$ndjson = "";
foreach ($params as $key => $item) {
$json = json_encode($item);
if (isset($params[$key + 1])) {
$ndjson .= $json . PHP_EOL;
} else {
$ndjson .= $json;
}
}
$resp = $this->client->request('POST', "/api/_bulk", ['body' => $ndjson]);
return $this->handleJson($resp);
}
/**
* 批量新增(不能指定zincSearch的主键)
* @param $index string 索引
* @param $data array 数据
* @return mixed
* @throws GuzzleException
* @throws Exception
*/
public function bulkV2($index, $data)
{
$indexName = $this->projectName . $index;
$params = [
'index' => $indexName,
];
foreach ($data as $k => $v) {
$params['records'][$k] = $v;
}
$resp = $this->client->request('POST', "/api/_bulkv2", ['json' => $params]);
return $this->handleJson($resp);
}
/**
* 新增或者编辑
* @param $index string 索引
* @param $id string 主键的值
* @param $data array 数据
* @return mixed
* @throws GuzzleException
* @throws Exception
*/
public function createOrUpdate($index, $id, $data)
{
$indexName = $this->projectName . $index;
$resp = $this->client->request('PUT', "/api/$indexName/_doc/$id", ['json' => $data]);
return $this->handleJson($resp);
}
/**
* 删除
* @param $index string 索引
* @param $id string 主键的值
* @return mixed
* @throws GuzzleException
* @throws Exception
*/
public function delete($index, $id)
{
$indexName = $this->projectName . $index;
$resp = $this->client->request('DELETE', "/api/$indexName/_doc/$id");
return $this->handleJson($resp);
}
/**
* 搜索
* @param $index string 索引
* @param $keyword string 关键词
* @param $filed array 需要显示的字段
* @param $from int 开始查询的下标,默认为0
* @param $maxResult int 查询的条数,默认为20
* @param $searchType string 搜索模式,默认为match
* @return array
* @throws GuzzleException
* @throws Exception
*/
public function search($index, $keyword, array $filed = [], $from = 0, $maxResult = 20, $searchType = 'match')
{
$indexName = $this->projectName . $index;
$json = [
'search_type' => $searchType,
'query' => [
'term' => $keyword
],
'from' => $from,
'max_results' => $maxResult,
'_source' => $filed
];
$resp = $this->client->request('POST', "/api/$indexName/_search", ['json' => $json]);
$result = $this->handleJson($resp);
$result = $result['hits']['hits'];
return array_column($result, '_source');
}
/**
* 相似推荐
* @param $index string 索引
* @param $field string 搜索的字段名
* @param $keyword string 关键词
* @param $idField string 主键
* @param $id string 主键的值(相似推荐排除自己)
* @param $form int 开始查询的下标,默认为0
* @param $size int 查询的条数,默认为20
* @return array
* @throws GuzzleException
* @throws Exception
*/
public function esSearch($index, $field, $keyword, $idField, $id, $form = 0, $size = 20)
{
$indexName = $this->projectName . $index;
$json = [
'query' => [
'bool' => [
'must' => [
'match' => [
$field => [
'query' => $keyword,
]
]
],
'must_not' => [
'match' => [
$idField => [
'query' => $id
]
]
]
]
],
'from' => $form,
'size' => $size,
];
$resp = $this->client->request('POST', "/es/$indexName/_search", ['json' => $json]);
$result = $this->handleJson($resp);
$result = $result['hits']['hits'];
return array_column($result, '_source');
}
/**
* 按条件获取数据列表
* @param $index string 索引
* @param $params array 搜索的条件
* @return array
* @throws GuzzleException
* @throws Exception
*/
public function request($index, $params)
{
$indexName = $this->projectName . $index;
$resp = $this->client->request('POST', "/es/$indexName/_search", ['json' => $params]);
$result = $this->handleJson($resp);
$result = $result['hits']['hits'];
return array_column($result, '_source');
}
}