elasticsearch联想加搜索实例

时间:2022-06-01 18:34:52

//搜索框具体的ajax如下:

<form class="form-wrapper cf">
<img src="__PUBLIC__/Home/img/shousuo.png" id="sousuo" style="position:absolute;margin-left:5px;height:20px;width:20px;margin-top:47px;text-align:center;" alt="">
<input type="text" id="content" style="height:42px;width:535px;margin-top:30px; padding-left:26px;" placeholder="输入问题搜索一下" required>

<button type="button" id="submitSearch" class="abutton">搜索一下
</button>
</form>

<script>
$(function () {
// 联想
$("#content").autocomplete({
contentType : 'application/x-www-form-urlencoded; charset=utf-8',
source: function(request,response){
$.ajax({
url: "{:U('Index/get_complation')}",
data: {keyword: $('#content').val()},
dataType: "json",
type: "post",
success: function (data) {
response($.map(data, function(item) {
return item;
}));
}
});
}
});
// 点击搜索
$('#submitSearch').click(function () {
// 获取输入框的值
var title = $('#content').val();
search(title);
});
});
function search(title){
$.ajax({
url: "{:U('Index/get_question')}",
data: {title: title},
dataType: "json",
type: "post",
success: function (data) {
if(data.status == -1){

$('.soucontent').hide();
$('#search-no-result').show();
}else{
$('#search-no-result').hide();
// 显示问题详情
$('.soucontent').show();
$('#detail-title').html(data.title); // 标题
$('#detail-content').html(data.content); // 内容
}
}
});
}
</script>

  封装搜索类(这里的搜索类没有用到数据库规定的分数,运用搜索的分数进行运算最后得出的排名):

     

<?php
/**
* Created by PhpStorm.
* User: nihuan
* Date: 16-12-17
* Time: 下午1:32
* Desc: 搜索方法类
*/
namespace Org\Util;
require '/alidata/webroot/elasticsearch/xiaodu/EsPHP/vendor/autoload.php';

class EsSearch
{
private $DEFAULT_SCORE_KEYWORD = 50;
private $DEFAULT_SCORE_TITLE = 40;
private $DEFAULT_SCORE_CONTENT = 30;

private $index = 'xiaodu';
private $es;

public function __construct()
{
Vendor('Elasticsearch.autoload');
$hosts = [
 
 
'192.168.1.1:9201',
'192.168.1.2:9201',
'192.168.1.3:9201'
];
$params['hosts'] = $hosts;
//连接ES服务器
$this->es = new \Elasticsearch\Client($params);
}

/**
* 搜索提示列表
* @Version 1.0
* @Date 16-12-17
* @param array $elastic
* @param $page
* @return array
*/
public function complation($elastic = array(), $page)
{
$text = array();
$keyword = $this->extractArgument($elastic, 'keyword');
$type = $this->extractArgument($elastic, 'type');
$field = $this->extractArgument($elastic, 'field');
$params['index'] = $this->index;
$format_keyword = $this->formatKeyword($keyword);
if ($format_keyword == $keyword) {
$params['body'] = array(
$type . '-suggest' => array(
'text' => $keyword,
'completion' => array(
'field' => $field,
'size' => $page
)
)
);
} else {
$params['body'] = array(
$type . '-suggest' => array(
'text' => $keyword,
'completion' => array(
'field' => 'keyword_pinyin_suggest',
'size' => $page
)
)
);
}
$result = $this->es->suggest($params);
if ($result[$type . '-suggest'] != false) {
foreach ($result[$type . '-suggest'][0]['options'] as $key => $value) {
$text[$key] = trim($value['text']);
}
}
return $text;
}

// public function question($elastic = array(),$size,$page = 0)
// {
//// $data = $others = [];
// $resultArray = [];
// $keyword = $this->extractArgument($elastic, 'keyword');
// $type = $this->extractArgument($elastic, 'type');
// $params = [
// 'index' => $this->index,
// 'type' => $type,
// 'from' => $page,
// 'size' => $size
// ];
// $params['body']['sort'] = array(
// '_score' => array(
// 'order' => 'desc'
// )
// );
// $must = [];
// if (!empty($keyword)) {
// array_push($must, array(
// 'multi_match' => array(
// 'query' => $keyword,
// 'fields' => array('keyword', 'title^2', 'content'),
// 'operator' => 'or'
// )
// ));
// }
// $params['body']['query']['bool']['must'] = $must;
// $result = $this->es->search($params);
//// if($result != false){
//// $current_result = current($result['hits']['hits']);
//// if(!empty($current_result)){
//// $data['title'] = $current_result['_source']['title'];
//// $data['content'] = str_replace("&nbsp;", "", strip_tags($current_result['_source']['content']));;
////// $data['asid'] = (int)$current_result['_source']['asid'];
//// $data['ask_id'] = (int)$current_result['_source']['asid'];
//// $data['fenshu'] = (int)$current_result['_source']['fenshu'];
//// }
//// unset($result['hits']['hits'][0]);
// foreach ($result['hits']['hits'] as $key => $val) {
//// array_push($others,['asid' => (int)$val['_source']['asid'], 'other_title' => $val['_source']['title']]);
// array_push($resultArray, ['id' => (int)$val['_source']['asid'], 'title' => $val['_source']['title'], 'fenshu' => $val['_source']['fenshu']]);
// }
// // }
//// return ['info' => $data, 'others' => $others];
// return $resultArray;
// }

public function questionKeyword($elastic, $searchField)
{
// $keyword = $elastic['keyword'];
// $type = $elastic['type'];
$keyword = $this->extractArgument($elastic, 'keyword');
$type = $this->extractArgument($elastic, 'type');

$params = [
'index' => $this->index,
'type' => $type,
'from' => 0,
'size' => 100
];
$params['body']['sort'] = array(
'_score' => array(
'order' => 'desc'
)
);
$must = [];
if (!empty($keyword)) {
array_push($must, array(
'multi_match' => array(
'query' => $keyword,
'fields' => array($searchField),
'operator' => 'and'
)
));
}
$params['body']['query']['bool']['must'] = $must;
$result = $this->es->search($params);
return $result;
}

public function question($elastic, $size, $page)
{
$keyword = $elastic['keyword'];

$resultArray = [];
$params['body']['sort'] = array(
'_score' => array(
'order' => 'desc'
)
);

$resultKeyword = $this->questionKeyword($elastic, 'keywords');
//var_dump($resultKeyword);
$resultTtitle = $this->questionKeyword($elastic, 'title^2');
$resultContent = $this->questionKeyword($elastic, 'content');

$mapResult = array();

foreach ($resultKeyword['hits']['hits'] as $key => $val) {
$keywordsArray = json_decode($val['_source']['keywords_array'], true);
$tempItem = $this->matchKeyword($keywordsArray, $keyword);
$fenshu = $this->DEFAULT_SCORE_KEYWORD;
if($tempItem)
{
$fenshu = $tempItem['fenshu'];
}

if($mapResult[(int)$val['_source']['asid']])
{
continue;
}

$itemResult = array();

$itemResult['id'] = (int)$val['_source']['asid'];
$itemResult['title'] = $val['_source']['title'];
$itemResult['fenshu'] = $val['_source']['fenshu'];
$itemResult['indexScore'] = floatval($fenshu);

array_push($resultArray, $itemResult);

$mapResult[$itemResult['id']] = $itemResult;
}

foreach ($resultTtitle['hits']['hits'] as $key => $val) {
$fenshu = $this->DEFAULT_SCORE_TITLE;

if($mapResult[(int)$val['_source']['asid']])
{
continue;
}

$itemResult = array();

$itemResult['id'] = (int)$val['_source']['asid'];
$itemResult['title'] = $val['_source']['title'];
$itemResult['fenshu'] = $val['_source']['fenshu'];
$itemResult['indexScore'] = floatval($fenshu);

array_push($resultArray, $itemResult);

$mapResult[$itemResult['id']] = $itemResult;
}
foreach ($resultContent['hits']['hits'] as $key => $val) {
$fenshu = $this->DEFAULT_SCORE_CONTENT;

if($mapResult[(int)$val['_source']['asid']])
{
continue;
}

$itemResult = array();

$itemResult['id'] = (int)$val['_source']['asid'];
$itemResult['title'] = $val['_source']['title'];
$itemResult['fenshu'] = $val['_source']['fenshu'];
$itemResult['indexScore'] = floatval($fenshu);

array_push($resultArray, $itemResult);

$mapResult[$itemResult['id']] = $itemResult;
}
$result =$this->sortArrByField($resultArray, 'indexScore', false);
$result = array_slice($result, 0 , $size);
return $result;
}

// 多维数组根据某一个字段 排序
public function sortArrByField(&$array, $field, $desc = false)
{
$fieldArr = array();
foreach ($array as $k => $v) {
$fieldArr[$k] = $v[$field];
}
$sort = $desc == false ? SORT_DESC : SORT_ASC;
array_multisort($fieldArr, $sort, $array);
return $array;
}

/**
* @param array $params
* @param string $arg
*
* @return null|mixed
*/
protected function matchKeyword($keywordsArray, $keyword)
{
if(!$keywordsArray || !$keyword)
{
return null;
}

foreach ($keywordsArray as $key => $item) {
if(strcmp($keyword, $item['keyword']) == 0)
{
return $item;
}
}

return null;
}

/**
* @param array $params
* @param string $arg
*
* @return null|mixed
*/
protected function extractArgument(&$params, $arg)
{
if (is_object($params) === true) {
$params = (array)$params;
}

if (isset($params[$arg]) === true) {
$val = $params[$arg];
unset($params[$arg]);
return $val;
} else {
return null;
}
}

/**
* @param $keyword
* @return string
* 格式化搜索关键词
*/
protected function formatKeyword($keyword)
{
$string = '';
$pattern = '/[^\x00-\x80]/';
if (!preg_match($pattern, $keyword)) {
$numPattern = '/[0-9]/';
if (!preg_match($numPattern, $keyword)) {
$params = "/[^aoeiuv]?h?[iuv]?(ai|ei|ao|ou|er|ang?|eng?|ong|a|o|e|i|u|ng|n)?/";
preg_match_all($params, $keyword, $result);
if (!empty($result[0])) {
foreach ($result[0] as $key => $value) {
if (!empty($value)) {
$string .= $value . ' ';
} else {
continue;
}
}
$string = substr($string, 0, strlen($string) - 1);
}
}
}
$string = empty($string) ? $keyword : $string;
return $string;
}

}

elasticsearch联想加搜索实例

elasticsearch联想加搜索实例

elasticsearch联想加搜索实例