<?php
/**
  * @method 全文搜索
  * @author soul
  * @copyright 
  */
class Ypc2Elastic extends Ypc2Base
{
	public $index = 'b2cmodel';
	public $client = null;

	public function __construct()
	{
		parent::__construct();
		$this->client = Elasticsearch\ClientBuilder::create()->setHosts(mvc::$cfg['ES'])->build();
	}

	/**
	  * @method 创建索引
	  * @author soul 
	  * @return
	  */
	public function createIndex()
	{
		try{
			$params = [
				'index' => $this->index,
				'body' => [
					'settings' => [
						'number_of_shards' => 1,
						'number_of_replicas' => 0
					],
					'mappings' => [
						'_source' => [
							'enabled' => true
						],
						'properties' => [
							'mod3_id' => [
								'type' => 'integer',
							],
							'mod3_word' => [
								'type' => 'text'
							]
						]
					]
				]
			];
			$response = $this->client->indices()->create($params);
		}catch (Exception $e) {
			return LibFc::ReturnData(false, '检索引擎不可用：'.$e->getMessage());
		}
		return LibFc::ReturnData(true, true); 
	}


	/**
	  * @method 删除索引
	  * @author soul 
	  * @return
	  */
	public function delIndex()
	{
		try{
			$this->client->indices()->delete(['index'=>$this->index]);
		}catch (Exception $e) {
			return LibFc::ReturnData(false, '检索引擎不可用：'.$e->getMessage());
		}
		return LibFc::ReturnData(true, true);
	}


	/**
	  * @method 重置配件全文搜索  $shopId && $proIdArr 同时为空时，重置所有
	  * @param  $shopId int 指定店铺
	  * @param  $proIdArr array 指定配件ID
	  * @author soul 
	  * @return
	  */
	public function updateItemWord()
	{
		set_time_limit(0);
		$Ypc2Model = new Ypc2Model();
		$mres = $Ypc2Model->getModel(3, ['mod3_id,brand_name,make_name,mod1_name,mod2_name,mod3_name,mod3_engine']);
		$add = [];
		foreach($mres['data'] as $k=>$v){
			$v['mod3_word'] = $v['mod3_name'].','.$v['mod2_name'].','.$v['mod1_name'].','.$v['make_name'].','.$v['brand_name'].','.$v['mod3_engine'];
			$v['mod3_word'] = LibFc::fromatKeyword($v['mod3_word']);
			$add[] =  ['index'=>['_index' =>$this->index, '_id'=>$v['mod3_id']]];
			$add[] = [
				'mod3_id' => $v['mod3_id'],  
				'mod3_word' => $v['mod3_word'],
			];
		}
		$this->delItemWord(array_keys($mres['data'], 'mod3_id'));
		$this->client->bulk(['body'=>$add]);
		return LibFc::ReturnData(true, true); 
	}

	/**
	  * @method 删除配件索引
	  * @param  $idArr array 指定ID
	  * @author soul 
	  * @return
	  */
	public function delItemWord($idArr)
	{
		if(!empty($idArr)){
			$params = [
				'index' => $this->index,
				'body'  => [
					'query' => [  
						"bool"=>[ 
						  "must"=>[
							"terms"=>["mod3_id"=>$idArr]
						]
					  ]
					]
				]
			];
			$this->client->deleteByQuery($params);
		}
		return LibFc::ReturnData(true, true); 
	}

	/**
	  * @method 搜索
	  * @param  $params array ['word'=>'', 'count'=>10000, 'match'=>0|1优先精准匹配]
	  * @author soul 
	  * @return
	  */
	public function searchId($params)
	{
		if(empty($params['count'])) $params['count'] = 10000;
		$re = ["、",",","，",";","；","\n","\t","\r", ' '];
		$keyword = str_replace($re, ',', $params['word']);
		$wordArr = explode(',', $keyword);
		$must = [["match"=>['mod3_word' =>$params['word']]]];	
		$query = $must[0];
		$blparams = [
			'index' => $this->index,
			'body' => [ 
				'query' => $query,
				'size'=>(int)$params['count']
			]
		];
		$response = $this->client->search($blparams);
		
		$hits = $response['hits']['hits'];
		//相关性有问题，优先排有重叠的
		$ids = []; 
		$newhits = [];
		$maxHit = 0;
		foreach($hits as $k=>$v){
			$v['hitcount'] = 0; 
			foreach($wordArr as $vv){
				if(mb_strlen($vv) > 1 && stripos($v['_source']['mod3_word'], $vv) !== false){
					$v['hitcount']++;
				}
			}
			if($v['hitcount'] > 0){
				$newhits[] = $v;
				if($maxHit < $v['hitcount']) $maxHit = $v['hitcount'];
			}
		}
		if($maxHit > 0){
			foreach($newhits as $v){
				if($v['hitcount'] == $maxHit){
					$ids[] = $v['_id'];
				}

			}
		}
		if(!empty($hits) && empty($ids)){
			$lastScore = $hits[0]['_score'];
			foreach($hits as $k=>$v){
				if(($lastScore - $v['_score'])/ $lastScore < 0.2){
					$ids[] = $v['_id'];
				}
			}
		}
		return LibFc::ReturnData(true, $ids);
	}
}