<?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();
}
}
}