es 搜索searchapi yii2 php代码
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2017/3/9 * Time: 19:16 */ namespace searchapi\controllers; use Yii; use yii\web\Controller; use searchapi\models\CarBrandInfo; use searchapi\models\CarBrandType; use searchapi\models\CarBrandTypeInfo; use searchapi\models\CarBrandSonTypeInfo; use searchapi\models\CarFactory; use yii\data\Pagination; use yii\helpers\BaseJson; use Elasticsearch; class QueryController extends Controller { private static $debug =false; //是否调试 const ES_INDEX ='ccindex'; const ES_TYPE ='cctype'; public function beforeAction($action) { //echo md5('1502267488'.'ECCBC87E4B5CE2FE28308FD9F2A7BAF3');exit;#73d79682dd9d40aa9f9bab9c3558ccd1 $time = Yii::$app->request->get('time'); $token = Yii::$app->request->get('token'); self::$debug =Yii::$app->request->get('debug','false'); $result = [ 'data' =>[], 'msg' =>'', 'status' =>1, ]; //判断验证 if(empty($time) || empty($token)){ $result['status'] =0; $result['msg'] ='缺少验证'; } elseif(time()-600>$time){ $result['status'] =0; $result['msg'] ='请求超时'; }elseif($token!=md5($time.\CEnv::TOKEN_SALT)){ $result['status'] =0; $result['msg'] ='token错误'; } if($result['status']==0){ self::returnResult($result); }else{ return parent::beforeAction($action); // TODO: Change the autogenerated stub } } /** * @inheritdoc */ public function actions() { return [ 'error' => [ 'class' => 'yii\web\ErrorAction', ], ]; } /** * 关键词查询文章 */ public function actionQuery(){ $result = [ 'data' =>[], 'msg' =>'', 'status' =>1, ]; $keywords =Yii::$app->request->get('keywords'); //关键词 $limit = Yii::$app->request->get('limit',10); //取的数量 $page = Yii::$app->request->get('page',1); //页数 $version = Yii::$app->request->get('version','v2.0'); //兼顾app老版本,v1.0老版本只能查news $key = 'search:'.$version.":".$keywords.":".$page.":".$limit; $rtnData = Yii::$app->cache->get($key); if($rtnData === false){ $offset = ($page-1)*$limit; if(!$keywords){ $result = array('msg'=>'参数为空','status'=>0); } $param = [ 'index'=>self::ES_INDEX, 'type'=>self::ES_TYPE, 'keywords'=>$keywords, 'offset'=>$offset, 'limit'=>$limit, 'fields'=>['_id'] ]; if($version == 'v1.0'){ //只能查询news $result['data'] = $this->queryEsnews($param); }else{ $result['data'] = $this->queryEs($param); } $rtnData = $result; if($result){ Yii::$app->cache->set($key,$rtnData,3600*24); } } self::returnResult($rtnData); } /** * 查询es news 和自媒体都有 * @param $param * @return array */ private function queryEs($param){ //实例化es 配置 $client = Elasticsearch\ClientBuilder::create() # ->setHosts(["localhost:9200"]) #->setHosts(["101.37.85.163:9200"]) ->setHosts([\CEnv::ES_API]) ->setRetries(1) ->build(); #$index = 'che_article'; #$type = 'car_archives'; $index = $param['index']; $type = $param['type']; $keywords = $param['keywords']; $from = $param['offset']; $size = $param['limit']; $fields = $param['fields']; $params = [ 'index' =>$index, 'type' => $type, #'analyzer' => 'elasticsearch-analysis-ik', 'from'=>$from, //offset 'size'=>$size, //limit //'analyzer'=>'ik', 'body' => [ 'query' => [ 'bool'=>[ "should"=>[ [ 'match'=>[ 'title'=>[ 'query'=>$keywords, 'boost'=>4, ] ] ], [ 'match'=>[ 'content'=>[ 'query'=>$keywords, 'boost'=>1, ] ] ], ], /*'must'=>[ [ 'match' => [ 'status' => [ 'query'=>0, ], ] ], ],*/ 'filter'=>[ "range"=>[ "inputtime"=>[ "gte"=>time()-7776000, //"gte"=>time()-31104000, "lte" =>time(), ], ] ] ], // 'analyzer' => 'ik', ], 'sort'=>[ '_score'=>[ 'order'=>'desc', ], 'inputtime'=>[ 'order'=>'desc', ], /*'id'=>[ 'order'=>'desc', ],*/ ], 'min_score'=>0.3 ], #'fields'=>$fields ]; $results = $client->search($params); $data=array(); if(!empty($results['hits'])) { $data['total']=($results['hits']['total']>500?500:$results['hits']['total']); foreach ($results['hits']['hits'] as $key=>$value) { $data['item'][]=[ 'id'=>$value['_source']['id'], 'score'=>$value['_score'], 'title'=>$value['_source']['title'], 'description'=>$value['_source']['description'], 'inputtime'=>date('Y-m-d H:i:s',$value['_source']['inputtime']), 'type'=>$value['_source']['type'], ]; #$data['idx'][]=$value['_id']; } } return $data; } /** * * 下拉关联的搜索 */ public function actionRelation(){ $result = [ 'data' =>[], 'msg' =>'', 'status' =>1, ]; //$data = []; $keywords = $this->formateKeywords(Yii::$app->request->get('keywords')); //关键词 $limit = Yii::$app->request->get('limit',10); //取的数量 if(!$keywords){ $result = array('msg'=>'参数为空','status'=>0); }else{ $result = $this->getRelation($keywords,$limit); } self::returnResult($result); //缓存量太大 /*$key = 'search:relation:'.$keywords.":".$limit; $rtnData = Yii::$app->cache->get($key); if($rtnData === false){ $result = $this->getRelation($keywords,$limit); $rtnData = $result; if($result){ Yii::$app->cache->set($key,$rtnData,3600*24); } }*/ } private function getRelation($keywords='',$limit=10){ $result = [ 'data' =>[], 'msg' =>'', 'status' =>1, ]; $data = []; //先判断是否完全匹配车系 $info = $this->isChexi($keywords); if($info){ $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name'],'level'=>3,'type'=>'']; $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."资讯",'level'=>3,'type'=>'news']; $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."图片",'level'=>3,'type'=>'photo']; $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."报价",'level'=>3,'type'=>'price']; $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."参配",'level'=>3,'type'=>'param']; $data[] = ['id'=>$info['car_brand_type_id'],'name'=>$info['car_brand_type_name']."口碑",'level'=>3,'type'=>'koubei']; $result['data'] = $data; return $result; } //判断是否完全匹配品牌 $info = $this->isBrand($keywords); if($info){ $brandId = $info['brand_id']; $data[] = ['id'=>$info['brand_id'],'name'=>$info['brand_name'],'level'=>1,'type'=>'']; //查询该品牌下的最热5个车系 $brandTypeInfoArr = CarBrandTypeInfo::getChexiByBrandId($brandId,($limit-1)); foreach ($brandTypeInfoArr as $k=>$v){ $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>'']; } #echo json_encode($result);exit; $result['data'] = $data; return $result; } //判断是否是厂商 $info = $this->isFactory($keywords); if($info){ $data[] = ['id'=>$info['brand_type_id'],'name'=>$info['brand_type'],'level'=>2,'type'=>'']; //如果完全品牌厂商则获取厂商下的车系 $factoryId = $info['brand_type_id']; $brandTypeInfoArr = CarBrandTypeInfo::getBrandTypeInfoByFactoryId($factoryId,$limit-1); foreach ($brandTypeInfoArr as $k=>$v){ $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>'']; } #echo json_encode($result);exit; $result['data'] = $data; return $result; } //如果都不完全匹配,先品牌、再厂商、最后车系 $brandArr = CarBrandInfo::getBrandInfoLikeName($keywords,$limit); foreach ($brandArr as $k=>$v){ $data[] = ['id'=>$v['brand_id'],'name'=>$v['brand_name'],'level'=>1,'type'=>'']; } $factoryArr = CarFactory::getFactoryLikeName($keywords,$limit); foreach ($factoryArr as $k=>$v){ $data[] = ['id'=>$v['brand_type_id'],'name'=>$v['brand_type'],'level'=>2,'type'=>'']; } $brandTypeInfoArr = CarBrandTypeInfo::getBrandTypeInfoLikeName($keywords,$limit); foreach ($brandTypeInfoArr as $k=>$v){ $data[] = ['id'=>$v['car_brand_type_id'],'name'=>$v['car_brand_type_name'],'level'=>3,'type'=>'']; } $data = array_slice($data,0, $limit); $result['data'] = $data; return $result; } /** * 更新es 文章状态 * @return bool */ public function actionUpdate(){ $ids = Yii::$app->request->get('ids'); //文章id $status = Yii::$app->request->get('status',0); //默认审核通过 0通过-1审核没通过 if(empty($ids)) return false; $idArray=explode(',',$ids); //实例化es 配置 $client = Elasticsearch\ClientBuilder::create() ->setHosts([\CEnv::ES_API]) ->setRetries(1) ->build(); foreach ($idArray as $v){ $params = [ 'index' => self::ES_INDEX, 'type' => self::ES_TYPE, 'id' => $v, ]; if($client->exists($params)==true){ $params['body']=[ 'doc'=>[ 'status' => $status ] ]; $response = $client->update($params); } } } /** * 删除es文章 * @return bool */ public function actionDelete(){ $ids = Yii::$app->request->get('ids'); //文章id if(empty($ids)) return false; $idArray=explode(',',$ids); //实例化es 配置 $client = Elasticsearch\ClientBuilder::create() ->setHosts([\CEnv::ES_API]) ->setRetries(1) ->build(); foreach ($idArray as $v){ $params = [ 'index' => self::ES_INDEX, 'type' => self::ES_TYPE, 'id' => $v, ]; if($client->exists($params)==true) $client->delete($params); } } //是不是完全品牌 private function isBrand($keywords=''){ $data = []; $data = CarBrandInfo::getBrandInfoBykeywords($keywords); if(!$data){ $brandArr = CarBrandInfo::getBrandInfoLikeName($keywords); //判断是不是唯一匹配品牌 if(count($brandArr) == 1){ $data = $brandArr[0]; } } return $data; } //是不是完全厂商 private function isFactory($keywords=''){ return CarFactory::getFactoryBykeywords($keywords); } //是不是完全车系 private function isChexi($keywords=''){ return CarBrandTypeInfo::getChexiBykeywords($keywords); } //白名单,卡宴—Cayenne 帕拉梅拉—Panamera,车系是英文 private function formateKeywords($keywords=''){ $keywordsArr = ['卡宴'=>'Cayenne','帕拉梅拉'=>'Panamera']; if(key_exists($keywords,$keywordsArr)){ $keywords = $keywordsArr[$keywords]; } return $keywords; } //返回结果 private static function returnResult($result = []){ if(self::$debug =='false'){ echo json_encode($result);Yii::$app->end(); }else{ echo "<pre>";print_r($result);Yii::$app->end(); } } }