Elasticsearch实现全文检索
合信招标网拥有千万级的招标信息,用户需要使用关键字进行标题、全文、日期、地区、行业、分类的检索。在mysql结构前,标题搜索限定时间内大约需要十几秒,全文搜索大约需要几分钟。
通过使用Elasticsearch对招标信息创建索引,实现全文检索豪秒级查询。
Elasticsearch核心类
<?php
defined('IN_DESTOON') or exit('Access Denied');
require DT_ROOT.'/vendor/autoload.php';
use Elasticsearch\ClientBuilder;
class es {
var $errmsg = errmsg;
function es() {
global $db, $table, $table_data, $MOD;
$hosts = [
// 等价于内联主机配置中使用 "https://username:password!#$?*abc@foo.com:9200/"
[
'host' => 'host地址',
'port' => '端口号',
'scheme' => 'http',
'user' => '用户名',
'pass' => '密码'
]
];
$this->client = ClientBuilder::create()->setHosts($hosts)->build();
}
function get_list($map = [], $order = 'addtime DESC') {
global $MOD, $pages, $page, $pagesize;
$offset = ($page - 1)*$pagesize;
//进行搜索
$date = isset($map['date'])?$map['date']:'';
$sstime = isset($map['sstime'])?$map['sstime']:0;
if($sstime){
$stime = $sstime;
}else{
if($date!=''){
switch ($date) {
case 'day':
$date_sum = 1;
break;
case 'week':
$date_sum = 7;
break;
case 'month':
$date_sum = 30;
break;
case 'quarter':
$date_sum = 90;
break;
case '6month':
$date_sum = 180;
break;
case 'year':
$date_sum = 365;
break;
default:
$date_sum = 365;
// code...
break;
}
}else{
$date_sum = 365;
}
$stime = strtotime(date('Y-m-d'))-$date_sum*24*3600;
}
$key = isset($map['keyword'])?$map['keyword']:'';
$catid_arr = isset($map['catid'])?$map['catid']:[];
// print_r($catid_arr);exit;
$area_arr = isset($map['areaid'])?$map['areaid']:[];
$hangye_arr = isset($map['hangye'])?$map['hangye']:[];
$title = isset($map['title'])?$map['title']:'';
$datetype = 'addtime';
$isedit = isset($map['isedit'])?$map['isedit']:0;
if($isedit){
$datetype = 'edittime';
}
$query = [
'query' => [
'bool' => [
'filter' => [
'0' =>[
'range' => [
$datetype => ['gt' => $stime]
]
]
]
]
],
'_source' => ['itemid','catid','filtercategory','addtime','edittime','linkurl','title','filteraddress','areaid','editor','username','hits']
];
//如果有结束日期则进行拼接
$totime = isset($map['totime'])?$map['totime']:0;
if($totime>0){
$query['query']['bool']['filter'][0]['range'][$datetype] = ['gt'=>$stime,'lt'=>$totime];
}
if($key!=''){
$key = str_replace("%","\" \"",$key);
$keystr = "\"".$key."\"";
// $query['query']['bool']['must']['query_string']['query'] = "content:(\"罗庄区\" \"毛锟\" \"桌椅和床\")";
$query['query']['bool']['must']['query_string']['query'] = "content:({$keystr})";
$query['query']['bool']['must']['query_string']['default_operator'] = "AND";
$query['query']['bool']['must']['query_string']['query'] = "({$keystr})";
$query['query']['bool']['must']['query_string']['default_operator'] = "AND";
}
if($title!=''){
$title = str_replace("%","\" \"",$title);
$keystr = "\"".$title."\"";
$query['query']['bool']['must']['query_string']['query'] = "title:({$keystr})";
$query['query']['bool']['must']['query_string']['default_operator'] = "AND";
}
if(count($catid_arr)){
$query['query']['bool']['filter'][]['terms']['catid'] = $catid_arr;
}
if(count($area_arr)){
// $query['query']['bool']['filter'][]['terms']['areaid'] = $area_arr;
$query['query']['bool']['filter'][]['terms']['filteraddress'] = $area_arr;
}
if(count($hangye_arr)){
$query['query']['bool']['filter'][]['terms']['filtercategory'] = $hangye_arr;
}
$params = [
'index' => 'hxzb_article_23',
'type' => 'zb_article_23',
'body' => array_merge([
'from' => $offset,
'size' => $pagesize,
"sort" => ['addtime'=>['order'=>'desc']]
],$query)
];
$results = $this->client->search($params);
$items = $results['hits']['total'];
$lists = $results['hits']['hits'];
$pages = pages($items, $page, $pagesize);
if($items < 1) return array();
//是否手机搜索
$ismobile = isset($map['mobile'])?$map['mobile']:0;
if($ismobile){
global $db;
$hcd = [];
//获取分类
$catef = $db->query("SELECT * FROM {$db->pre}category where moduleid=23");
while ($cf = $db->fetch_array($catef)) {
$hcd[$cf['catid']] = $cf;
}
// print_r($hcd);exit;
}
foreach($lists as $k=>$v){
$r = $v['_source'];
$r['adddate'] = timetodate($r['addtime'], 3);
$r['editdate'] = timetodate($r['edittime'], 3);
$r['alt'] = $r['title'];
$r['itemno'] = $k+1+ $offset;
if($r['filteraddress']==''){
$r['filteraddress'] = '全国';
}
if($ismobile){
$r['title'] = dsubstr($r['title'], 78, '...');
$r['title']=str_replace($title,"<font color='red'>".$title."</font>",$r['title']);
$r['catname'] = $hcd[$r[catid]]['catname'];
}
if($r['linkurl']!=''){
if(strpos($r['linkurl'], '://') === false) $r['linkurl'] = $MOD['linkurl'].$r['linkurl'];
}
$lists[$k] = $r;
}
return $lists;
}
public function delete($itemid){
$query = [];
$query['query']['bool']['must'][0]['term']['itemid'] = $itemid;
$params = [
'index' => 'hxzb_article_23',
'type' => 'zb_article_23',
'body' => $query
];
$jg = $this->client->deleteByQuery($params);
return 1;
}
}
?>