|
|
<?php |
|
|
namespace app\common\model; |
|
|
|
|
|
use think\Db; |
|
|
use think\Cache; |
|
|
|
|
|
class VodSearch extends Base { |
|
|
|
|
|
protected $name = 'vod_search'; |
|
|
|
|
|
public $maxIdCount = 1000; |
|
|
private $updateTopCount = 50000; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getResultIdList($search_word, $search_field, $word_multiple = false) |
|
|
{ |
|
|
$search_word = trim($search_word); |
|
|
$search_word = str_replace(',,', '', $search_word); |
|
|
if (strlen($search_word) == 0 || strlen($search_field) == 0) { |
|
|
return []; |
|
|
} |
|
|
|
|
|
if ($word_multiple === true) { |
|
|
$id_list = []; |
|
|
$search_word_exploded = explode(',', $search_word); |
|
|
foreach ($search_word_exploded as $search_word) { |
|
|
$id_list += $this->getResultIdList($search_word, $search_field); |
|
|
} |
|
|
$id_list = array_unique($id_list); |
|
|
return $id_list; |
|
|
} |
|
|
$search_key = md5($search_word . '@' . $search_field); |
|
|
$where = ['search_key' => $search_key]; |
|
|
$search_row = $this->where($where)->field("search_result_ids, search_hit_count")->find(); |
|
|
if (empty($search_row)) { |
|
|
$where_vod = []; |
|
|
$where_vod[$search_field] = ['LIKE', '%' . $search_word . '%']; |
|
|
$id_list = Db::name('Vod')->where($where_vod)->order("vod_id ASC")->column("vod_id"); |
|
|
$id_list = is_array($id_list) ? $id_list : []; |
|
|
$this->insert([ |
|
|
'search_key' => $search_key, |
|
|
'search_word' => mb_substr($search_word, 0, 128), |
|
|
'search_field' => mb_substr($search_field, 0, 64), |
|
|
'search_hit_count' => 1, |
|
|
'search_last_hit_time' => time(), |
|
|
'search_update_time' => time(), |
|
|
'search_result_count' => count($id_list), |
|
|
'search_result_ids' => join(',', $id_list), |
|
|
]); |
|
|
} else { |
|
|
$id_list = explode(',', (string)$search_row['search_result_ids']); |
|
|
$id_list = array_filter($id_list); |
|
|
$this->where($where)->update([ |
|
|
'search_hit_count' => $search_row['search_hit_count'] + 1, |
|
|
'search_last_hit_time' => time(), |
|
|
]); |
|
|
} |
|
|
$id_list = array_map('intval', $id_list); |
|
|
$id_list = empty($id_list) ? [0] : $id_list; |
|
|
return $id_list; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function isFrontendEnabled() |
|
|
{ |
|
|
$config = config('maccms'); |
|
|
|
|
|
if (!isset($config['app']['vod_search_optimise'])) { |
|
|
return false; |
|
|
} |
|
|
$list = explode('|', $config['app']['vod_search_optimise']); |
|
|
return in_array('frontend', $list); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function isCollectEnabled() |
|
|
{ |
|
|
$config = config('maccms'); |
|
|
|
|
|
if (!isset($config['app']['vod_search_optimise'])) { |
|
|
return false; |
|
|
} |
|
|
$list = explode('|', $config['app']['vod_search_optimise']); |
|
|
return in_array('collect', $list); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function checkAndUpdateTopResults($vod, $force = false) |
|
|
{ |
|
|
static $list; |
|
|
if (empty($vod['vod_id'])) { |
|
|
return; |
|
|
} |
|
|
if (is_null($list)) { |
|
|
$cach_name = 'vod_search_top_result_v2_' . $this->updateTopCount; |
|
|
$list = $force ? [] : Cache::get($cach_name); |
|
|
if (empty($list)) { |
|
|
$list = $this->field("search_key, search_word, search_field")->order("search_hit_count DESC, search_last_hit_time DESC")->limit("0," . $this->updateTopCount)->select(); |
|
|
$force === false && Cache::set($cach_name, $list, count($list) < ($this->updateTopCount / 10) ? 3600 : 86400); |
|
|
$this->clearOldResult(); |
|
|
} |
|
|
} |
|
|
$time_now = time(); |
|
|
foreach ($list as $row) { |
|
|
foreach (explode('|', $row['search_field']) as $field) { |
|
|
if (!isset($vod[$field]) || strlen($vod[$field]) == 0) { |
|
|
continue; |
|
|
} |
|
|
if (stripos($vod[$field], $row['search_word']) === false) { |
|
|
continue; |
|
|
} |
|
|
Db::execute("UPDATE `" . config('database.prefix') . $this->name . "` SET |
|
|
search_update_time='{$time_now}', |
|
|
search_result_count=search_result_count+1, |
|
|
search_result_ids=CONCAT(search_result_ids,',','{$vod['vod_id']}') |
|
|
WHERE search_key='{$row['search_key']}'"); |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getResultCacheMinutes($config = []) { |
|
|
|
|
|
$minutes = 20160; |
|
|
$config = $config ?: config('maccms'); |
|
|
if (isset($config['app']['vod_search_optimise_cache_minutes']) && (int)$config['app']['vod_search_optimise_cache_minutes'] > 0) { |
|
|
$minutes = (int)$config['app']['vod_search_optimise_cache_minutes']; |
|
|
} |
|
|
return $minutes; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function clearOldResult($force = false) |
|
|
{ |
|
|
|
|
|
$clear_seconds = $this->getResultCacheMinutes() * 60; |
|
|
|
|
|
$cach_name = 'interval_vs_clear_old_v1_' . $clear_seconds; |
|
|
$cache_data = Cache::get($cach_name); |
|
|
if ($force === false && !empty($cache_data)) { |
|
|
return; |
|
|
} |
|
|
Cache::set($cach_name, 1, min($clear_seconds, 86400)); |
|
|
|
|
|
$where = [ |
|
|
'search_field' => ['neq', 'vod_actor'], |
|
|
'search_update_time' => ['lt', time() - $clear_seconds], |
|
|
]; |
|
|
|
|
|
if ($force === true) { |
|
|
unset($where['search_field']); |
|
|
} |
|
|
$this->where($where)->delete(); |
|
|
} |
|
|
|
|
|
} |
|
|
|