php 封装 elasticsearch
<?php /** * elasticsearch封装类 * @author joniding * @date 2019-07-19 */ namespace PhpLib\Ec\Helpers; use Elasticsearch\ClientBuilder; use Illuminate\Http\Request; class ElasticSearch { public $config; public $api; public $index_name; public $index_type; public function __construct($index_name,$index_type) { try{ //加载配置文件 $this->config = config('elasticsearch'); //构建客户端对象 $this->api = ClientBuilder::create()->setHosts($this->config['hosts'])->build(); $this->index_name = $index_name; $this->index_type = $index_type; }catch (\Exception $e){ throw $e; } } /** * 初始化索引参数 * @author joniding * @return array */ public function initParams() { return [ 'index' => $this->index_name, 'type' => $this->index_type, ]; } /** * 创建一个索引 * @author joniding * @param $settings * @return array * @throws \Exception */ public function createIndex($settings = []) { try{ $initParams['index'] = $this->index_name; !empty($settings) && $initParams['body']['settings'] = $settings; $res = $this->api->indices()->create($initParams); }catch(\Exception $e){ throw $e; } return $res; } /** * 更新索引的映射 mapping * @author joniding * @param $data * @return array * @throws \Exception */ public function setMapping($data) { try{ $initParams = $this->initParams(); $initParams['body'] = $data; $res = $this->api->indices()->putMapping($initParams); }catch (\Exception $e){ throw $e; } return $res; } /** * 获取索引映射 mapping * @author joniding * @return array * @throws \Exception */ public function getMapping() { try{ $initParams = $this->initParams(); $res = $this->api->indices()->getMapping($initParams); }catch (\Exception $e){ throw $e; } return $res; } /** * 向索引中插入数据 * @author joniding * @param $data * @return bool * @throws \Exception */ public function add($data) { try{ $params = $this->initParams(); isset($data['id']) && $params['id'] = $data['id']; $params['body'] = $data['body']; $res = $this->api->index($params); }catch (\Exception $e){ throw $e; } if (!isset($res['_shards']['successful']) || !$res['_shards']['successful']){ return false; } return true; } /** * 批量插入数据 * @author joniding * @param $data * @return array * @throws \Exception */ public function bulk($data) { try{ if (empty($data['body'])) return false; $params = $this->initParams(); $params['body'] = $data['body']; $res = $this->api->bulk($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 检测文档是否存在 * @param $id * @return array|bool * @throws \Exception */ public function IndexExists($id) { try{ $params = $this->initParams(); $params['id'] = $id; $res = $this->api->exists($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 单字段模糊查询 * 满足单个字段查询(不带分页+排序)match 分词查询 * @author joniding * @param $data * @return array * @throws \Exception */ public function search($data = []) { try{ $params = $this->initParams(); if (!empty($data)){ $field = key($data); $query = [ 'match' => [ $field => [ 'query' => $data[$field], 'minimum_should_match' => '90%' //相似度,匹配度 ] ] ]; $params['body']['query'] = $query; } $res = $this->api->search($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 根据唯一id查询数据 * @author joniding * @param $id * @return array * @throws \Exception */ public function searchById($id) { try{ $params = $this->initParams(); $params['id'] = $id; $res = $this->api->get($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 根据关键字查询数据 * 多个字段查询:multi_match * @author joniding * @param $data * $data['condition'] 条件组合 * $data['es_size'] 每页显示数量 * $data['es_from'] 从第几条开始 * $data['es_sort_field'] 自定义排序字段 * @return array|bool * @throws \Exception */ public function searchMulti($data = []) { try{ if (!is_array($data)){ return []; } $params = $this->initParams(); if (array_key_exists('fields',$data)){ $params['_source'] = $data['fields']; } //分页 if (array_key_exists('page_size',$data)){ $params['size'] = !empty($data['page_size'])?$data['page_size']:1; //前端页码默认传1 $params['from'] = !empty($data['page'])?($data['page']-1)*$params['size']:0; unset($data['page_size'],$data['page']); } //排序 if (array_key_exists('sort_field',$data)){ $sort_file = !empty($data['sort_field'])?$data['sort_field']:'total_favorited'; $sort_rule = !empty($data['sort_rule'])?$data['sort_rule']:'desc'; $params['body']['sort'][] = [ ''.$sort_file.'' => [ 'order' => ''.$sort_rule.'', ] ]; unset($data['sort_field'],$data['sort_rule']); }else{ // $params['body']['sort'][] = [ // 'created_at' => [ // 'order' => 'desc', // ] // ]; } /** * 深度(滚动)分页 */ if (array_key_exists('scroll',$data)){ $params['scroll'] = $data['scroll']; } //条件组合 if (array_key_exists('condition',$data)){ $query = []; $condition = $data['condition']; /** * 组合查询 */ if (array_key_exists('bool',$condition)){ //必须满足 if (array_key_exists('must',$condition['bool'])){ foreach ($condition['bool']['must'] as $key => $val){ if (is_array($val)){ $query['bool']['must'][]['range'] = [ $key => [ 'gte' => $val[0], 'lte' => $val[1] ] ]; }else{ $query['bool']['must'][]['match'] = [ $key => $val ]; } } } } !empty($query) && $params['body']['query'] = $query; } $res = $this->api->search($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 查询索引是否存在 * @return array|bool * @throws \Exception */ public function exist() { try{ $params['index'] = $this->index_name; $res = $this->api->indices()->exists($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 根据唯一id删除 * @author joniding * @param $id * @return bool * @throws \Exception */ public function delete($id) { try{ $params = $this->initParams(); $params['id'] = $id; $res = $this->api->delete($params); }catch (\Exception $e){ throw $e; } if (!isset($res['_shards']['successful'])){ return false; } return true; } /** * 聚合统计,方差 * @param $data * @return array * @throws \Exception * @author:joniding * @date:Times */ public function searchAggs($data) { try{ if (!is_array($data)){ return []; } $query= []; $params = $this->initParams(); $params['size'] = 0; /** * 条件组合过滤,筛选条件 */ if (array_key_exists('condition',$data)){ $condition = $data['condition']; if (array_key_exists('bool',$condition)){ //必须满足 if (array_key_exists('must',$condition['bool'])){ foreach ($condition['bool']['must'] as $key => $val){ if (is_array($val)){ $query['bool']['must'][]['range'] = [ $key => [ 'gte' => $val[0], 'lte' => $val[1] ] ]; }else{ $query['bool']['must'][]['match'] = [ $key => $val ]; } } $params['body']['query'] = $query; } } } //分组、排序设置 if (array_key_exists('agg',$data)){ $agg = []; //字段值 if (array_key_exists('terms',$data['agg'])){ $agg['_result']['terms'] = [ 'field' => $data['agg']['terms'], 'size' => 500, ]; if (array_key_exists('order',$data['agg'])){ foreach ($data['agg']['order'] as $key => $val){ $fields = 'result.'.$key; $agg['_result']['terms']['order'] = [ $fields => $val ]; unset($fields); } } } //统计 if (array_key_exists('field',$data['agg'])){ $agg['_result']['aggs'] = [ 'result' => [ 'extended_stats' => [ 'field' => $data['agg']['field'] ] ] ]; } //日期聚合统计 if (array_key_exists('date',$data['agg'])){ $date_agg = $data['agg']['date']; //根据日期分组 if (array_key_exists('field',$date_agg)){ $agg['result'] = [ 'date_histogram' => [ 'field' => $data['agg']['date']['field'], 'interval' => '2h', 'format' => 'yyyy-MM-dd HH:mm:ss' ] ]; } if (array_key_exists('agg',$date_agg)){ //分组 if (array_key_exists('terms',$date_agg['agg'])){ $agg['result']['aggs']['result']['terms'] = [ 'field' => $date_agg['agg']['terms'], 'size' => 100, ]; } //统计最大、最小值等 if (array_key_exists('stats',$date_agg['agg'])){ $agg['result']['aggs']['result']['aggs'] = [ 'result_stats' => [ 'extended_stats' => [ 'field' => $date_agg['agg']['stats'] ] ] ]; } } } $params['body']['aggs'] = $agg; } \Log::info(json_encode($params)); $res = $this->api->search($params); }catch (\Exception $e){ throw $e; } return $res; } /** * 批量查询,只能根据id来查 * @param $data * @return array * @throws \Exception * @author:joniding * @date:2019/8/5 19:51 */ public function mGet($data) { try{ if (!is_array($data)) return []; //初始化索引 $params = $this->initParams(); if (array_key_exists('fields',$data)){ $query['ids'] = $data['fields']; $params['body'] = $query; } $res = $this->api->mget($params); return $res; }catch (\Exception $e){ throw $e; } } /** * 深度分页 * @param $data * @return array * @throws \Exception * @author:joniding * @date:2019/8/16 14:49 */ public function scroll($data) { try{ $params = [ 'scroll_id' => $data['scroll_id'], 'scroll' => '1m' ]; $res = $this->api->scroll($params); // \Log::info(json_encode($params)); if (isset($res['_scroll_id']) && $res['_scroll_id'] != $data['scroll_id']){ $this->api->clearScroll(['scroll_id' => $data['scroll_id'] ]); } return $res; }catch(\Exception $e){ throw $e; } } }