'mark', 'order' => 'desc' ] , [ 'order_field' => 'year', 'order' => 'desc' ] ]; return $this->_json_succ( $this->setOrderOther($orderArray) ); } /** * 设置语言 */ public function setLanguage() { $language = Request::param('language') ?? 'document_zh'; Session::set('language' , $language); return $this->_json_succ( [ 'language' => $language ] ); } /** * 搜索提示 */ public function searchTip() { $search = Request::param('search') ?? ''; if( ! $search) { return $this->_json_error('请求有误!'); } $field = Request::param('field') ?? 'name'; $diseases = CdssXyDisease::field($field) ->where('name' , 'like' , "%$search%") ->select() ->toArray() ?? []; $diseaseArr = empty($diseases) ? [] : array_values(array_filter(array_column($diseases , $field))); return $this->_json_succ( $diseaseArr ); } /** * 普通检索| 疾病别名 */ public function singleSearchRecommendDisease() { $keyword = Request::param('search') ?? ''; if( ! $keyword) { return $this->_json_error( '请求参数有误!' ); } $diseases = (new CdssXyDisease())->getNameAndAlias($keyword); return $this->_json_succ( $diseases ); } /** * 高级检索推荐疾病 | 疾病别名 */ public function searchRecommendDisease() { $keyword = Request::param('keyword') ?? ''; if( ! $keyword) { return $this->_json_error('请求有误!'); } $disease = CdssXyDisease::field('name , alias')->where('name' , $keyword)->find(); if(empty($disease)) { $disease = CdssXyDisease::field('name , alias')->whereOr('alias' , 'like' ,"%$keyword%")->find(); } $name = $disease->name; $alias = $disease->alias; if(stripos($alias , ';') !== false) { $newArray[] = $name; $aliasArr = explode(';' , $alias); $newArray = array_merge($newArray, $aliasArr); } elseif(stripos($alias , ';') !== false) { $newArray[] = $name; $aliasArr = explode(';' , $alias); $newArray = array_merge($newArray, $aliasArr); } else { $newArray[] = $name; $newArray[] = $alias; } $diseases = CdssXyDisease::field('name')->whereOr('name' , 'like' ,"%$keyword%")->select()->toArray(); $diseasesArr = array_column($diseases , 'name') ?? []; return $this->_json_succ( array_unique(array_merge($newArray, $diseasesArr)) ); } /** * 文献首页 * * @param $document string * @param $field string * @param $page int * @return Json */ public function index():Json { $uid = Request::param('uid') ?? '833456167'; $field = Request::param('field') ?? '*'; $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; //$index = $this->currentLanguage(); $index = 'document_zh'; $params = [ 'index' => $index, 'body' => [ 'from' => $limit, 'size' => $this->pagesize, 'query' => [ 'match_all' => (object)[] , // 查询全部 ], "_source" => $field, // 获取制定字段 //"sort" => $this->setOrderOther(); ], "preference" => "_primary_first" ]; //print_r($params);die; $result = $this->esCommonGetData($params); return $this->_json_succ( $this->dataAssemble( $uid , $result['total'] , $result['data'] ) ); } /** * 文献详情 */ public function esDocumentDetail() { $periodicalMd5 = Request::param('periodical_md5') ?? ''; $uniqId = Request::param('uniq_id') ?? ''; $pmid = Request::param('PMID') ?? ''; if( ! $periodicalMd5 && ! $uniqId && ! $pmid) { return $this->_json_error('请求参数有误!'); } $index = 'document_en,document_zh'; if($periodicalMd5 || ($periodicalMd5 && $uniqId)) { $field = 'periodical_md5'; $value = $periodicalMd5; } if($uniqId && ! $periodicalMd5) { $field = 'uniq_id'; $value = $uniqId; } if ($pmid && ! $uniqId) { $field = 'PMID'; $value = $pmid; } $uid = Request::param('uid') ?? '833456167'; $params = [ 'index' => $index, 'body' => [ 'query' => [ "constant_score" => [ "filter" => [ "term" => [ $field => $value ] ], ], ], ] ]; $client = $this->getEsClient(); $result = $client->search($params); if( 0 == $result['hits']['total']) { return $this->_json_error('未查询到数据!'); } $detail = $result['hits']['hits'][0]['_source'] ?? []; $detail['is_collection'] = EsCollection::checkIsCollection($uid , $value); $detail['click_count'] = ClickCount::where('md5' , $value)->value('click_count'); $titleArr = [ 'N1站淋巴结检出数目对pT1~3N0M0非小细胞肺癌患者预后的影响' , '滋燥养荣颗粒治疗非小细胞肺癌EGFRIs相关皮肤干燥症阴虚血燥证有效性及安全性的长期随访研究', '胸腔镜肺叶切除术与肺段切除术治疗T1bN0M0 期非小细胞肺癌的回顾性队列研究' ]; //if(in_array($detail['title'] , $titleArr)) { // $detail['pdf_url'] = 'https://jm.jiankangche.cn/zsk/pdf/202302082310.pdf'; //} else { // $detail['pdf_url'] = $this->checkDocPdfIsExist($detail['pdf_name'] ?? ''); //} $datail['pdf_url'] = ''; ClickCount::docClickCount($value); return $this->_json_succ( $detail ); } /** * 检测pdf文档地址是否可访问 */ private function checkDocPdfIsExist($pdf_name = '') { if( ! $pdf_name ) { return ""; } $url = 'https://jm.jiankangche.cn/zsk/pdf/'.$pdf_name; $check = get_headers($url); return stripos($check[0] , '200') !== false ? $url : ""; } /** * 相关文献 */ public function getDocumentByTag() { $title = Request::param('title') ?? ''; $tag = Request::param('tag') ?? 'similarity'; $uid = Request::param('uid') ?? '833456167'; if( ! $title || ! $tag ) { return $this->_json_error('请求错误!'); } $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; $index = $this->currentLanguage(); $params = [ 'index' => $index, 'body' => [ 'size' => $this->pagesize, 'from' => $limit, 'query' => [ "match"=>[ 'title' => [ 'query' => $title, 'boost' => 3, // 权重 ], ], ], ] ]; $result = $this->esCommonGetData($params); return $this->_json_succ( $this->dataAssemble($uid , $result['total'] , $result['data']) ); } /** * 参考文献 */ public function references() { } /** * 最高 | 最新 期刊 * * @param $tag string 标识 * @param $page int 分页 * @return Json */ public function getAlbumByTag():Json { $tag = Request::param('tag') ?? 'highest'; if( ! $tag) { return $this->_json_error('请求参数有误!'); } /** * 最高 */ if('highest' === $tag) { $orderField = 'total_citations_number.keyword'; $order = 'desc'; } /** * 最新 */ if('recently' === $tag) { $orderField = 'first_time.keyword'; $order = 'desc'; } $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; $index = $this->currentLanguage(); $albumIndex = 'document_zh' === $index ? 'album' : 'album_en'; $params = [ 'index' => $albumIndex, 'body' => [ 'from' => $limit, 'size' => $this->pagesize, 'query' => [ 'match_all' => (object)[] , // 查询全部 ], //"_source" => $field, // 获取制定字段 "sort" => $this->setOrder($orderField , $order), ], ]; return $this->_json_succ( $this->esCommonGetData($params) ); } /** * 搜索 */ public function conditionFilter() { $searchType = Request::param('search_type') ?? 'many'; if( ! $searchType ) { $this->_json_error('参数请求错误!'); } /** * 排序 */ $orderField = Request::param('order_field') ?? 'year'; $order = Request::param('order') ?? 'desc'; $searchTag = Request::param('search_tag') ?? 2; $uid = Request::param('uid') ?? '833456167'; /** * 点击量排序 */ if('click_count' === $orderField) { $orderField = 'year'; $otherOrderField = 'click_count'; $otherOrder = $order; } else { $otherOrderField = ''; $otherOrder = ''; } /** * 年份筛选 */ $year = Request::param('year') ?? ''; /** * 高级搜索数组 */ $conditionArray = Request::param('condition') ?? ''; if( ! $conditionArray ) { $this->_json_error('搜索条件有误!'); } foreach($conditionArray as $k => $v) { if( ! $v['field_value']) { unset($conditionArray[$k]); } if ($searchType === 1){ //有别名的情况跳过 continue; } /** * 标题搜索 匹配英文 */ if ($v['select_field'] == 'title'){ //$translated_field_value = $this->translate($v['field_value']); $translated_field_value = null; $conditionArray[$k] = [ "select_field"=> "title", "field_value" => $v['field_value'], "select_type"=> "match", "select_condition"=> "or" ]; if ($translated_field_value){ $conditionArray[] = [ "select_field"=> "title", "field_value"=>$translated_field_value, "select_type"=> "match", "select_condition"=> "or" ]; } } /** * 主题搜索 匹配英文 */ if ($v['select_field'] == 'theme'){ $conditionArray[] = [ "select_field"=> "title", "field_value" => $v['field_value'], "select_type"=> "match", "select_condition"=> "or" ]; $conditionArray[] = [ "select_field"=> "abstract", "field_value" => $v['field_value'], "select_type"=> "match", "select_condition"=> "or" ]; $conditionArray[] = [ "select_field"=> "keyword", "field_value" => $v['field_value'], "select_type"=> "match", "select_condition"=> "or" ]; //$translated_field_value = $this->translate($v['field_value']); $translated_field_value = null; if ($translated_field_value){ $conditionArray[] = [ "select_field"=> "title", "field_value"=>$translated_field_value, "select_type"=> "match", "select_condition"=> "or" ]; $conditionArray[] = [ "select_field"=> "abstract", "field_value"=>$translated_field_value, "select_type"=> "match", "select_condition"=> "or" ]; $conditionArray[] = [ "select_field"=> "keyword", "field_value"=>$translated_field_value, "select_type"=> "match", "select_condition"=> "or" ]; } } } /** * 连接es */ $client = $this->getEsClient(); /** * 获取查询结果 */ $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; /** * 当前索引名称 */ // $index = $this->currentLanguage(); $index = 'document_zh,document_en'; /** * 组装es-query */ $array = $this->combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag , $year); //dd(json_encode($array['params'],JSON_UNESCAPED_UNICODE)); $result = $client->search( $array['params'] ); /** * 数据以及数据总数 */ $total = $result['hits']['total']; if(0 == $total) { return $this->_json_error('未检索到结果!'); } $data = $result['hits']['hits']; /** * 特殊搜索处理 (非小细胞肺癌) */ $fieldValueArr = array_column($conditionArray , 'field_value'); $fieldValue = '非小细胞肺癌'; if(in_array($fieldValue , $fieldValueArr)) { $data[0] = $this->docDetail($index); } $totalPage = ceil($total / $this->pagesize); /** * 关键词高亮 */ foreach($data as $key => $value) { if(isset($value['highlight']['author']) ) { $authorList = explode(";" , $value['highlight']['author'][0]); } else { $authorList = $data[$key]['_source']['author_list'] ?? ''; } if(isset($value['highlight']['keyword']) ) { $keywordList = explode(";" , $value['highlight']['keyword'][0]); } else { $keywordList = $data[$key]['_source']['keyword_list'] ?? ''; } $data[$key]['_source']['title'] = isset($value['highlight']['title']) ? $value['highlight']['title'][0] : $data[$key]['_source']['title']; $data[$key]['_source']['abstract'] = isset($value['highlight']['abstract']) ? $value['highlight']['abstract'][0] : $data[$key]['_source']['abstract']; $data[$key]['_source']['author_list'] = $authorList; $data[$key]['_source']['keyword_list'] = $keywordList; } if('many' === $searchType) { /** * 记录查询历史 */ $content = $array['content'] ?? ''; $searchDesc = ''; $searchConditions = ''; $countContent = count($content); foreach ($content as $k => $v) { if($k == ($countContent - 1)) { $selectCondition = ''; } else { $selectCondition = $content[$k+1]['select_condition']; } $searchDesc.= '('.$v['select_field_desc'] . '=' . $v['field_value'].')' . $selectCondition . ' '; $searchConditions.= $v['select_condition'] . ' '; } $checkIsExistSearchHistory = History::where( [ 'uid' => $uid , 'search_desc' => $searchDesc ] )->find(); if( ! $checkIsExistSearchHistory) { History::create( [ 'uid' => $uid , 'content' => json_encode($array['content'] ?? '') , 'tag' => $searchTag , 'search_doc_count' => $total , 'search_desc' => $searchDesc , 'search_conditions' => $searchConditions ] ); } } $newArray = []; /** * 获取实际返回数据源 */ foreach ($data as $value) { $newArray[] = $value['_source']; } $combineData = $this->dataAssemble($uid , $total, $newArray , $otherOrderField , $otherOrder); /** * 相关作者 */ $combineData['authors'] = $this->relatedAuthors($result['aggregations']['author_list']); /** * 搜索关键词 */ $combineData['keyword'] = $this->searchKeyword($conditionArray[0]['field_value'] ?? ''); /** * 研究趋势 */ $combineData['research_trends'] = $this->researchTrends($year , $conditionArray , $index); /** * 关联研究 */ $combineData['associationStudy'] = $this->associationStudy($result['aggregations']['keyword_list']); $combineData['total_page'] = $totalPage; $combineData['total'] = $total; return $this->_json_succ( $combineData ); } public function translate($text) { $url = config('translate.request_url.get_profile_url'); $response = $this->curlGetRequest($url); if( ! $response) { return false; } $profile = json_decode($response , true) ?? ''; if( ! $profile) { return $this->_json_error('系统繁忙,稍候再试!'); } /** * 团队ID */ $teamId = $profile['data']['member'][0]['team_id']; $url = config('translate.request_url.text_translate_url'); $realRequestUrl = $url.$teamId; if (preg_match("/^[^\x80-\xff]+$/", $text)){ $source = 'en'; $target = 'zh'; }else{ $source = 'zh'; $target = 'en'; } /** * 请求参数 */ $requestParams = [ "source" => $source, "target" => $target, "domain" => "medical" , 'lines' => [ [ 'id' => 0 , 'text' => $text ] ] ]; $response = $this->curlPostRequest($realRequestUrl , $requestParams , '9b4a6c0f23f50eb6530d6cc4a03b0e96a2f051db'); $arr = json_decode($response , true); $data = $arr['data']; return $data[0]['text'] ?? ''; } /** * 获取详情 */ protected function docDetail($index) { $params = [ 'index' => $index, 'body' => [ 'query' => [ "constant_score" => [ "filter" => [ "term" => [ 'uniq_id' => '001' ] ], ], ], ] ]; $client = $this->getEsClient(); $result = $client->search($params); return $result['hits']['hits'][0] ?? []; } /** * 组装条件 */ protected function combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag) { if(1 === $searchTag) { /** * 普通检索 有别名和标准名称情况 */ $fieldVal = $conditionArray[0]['field_value']; $names = explode(',',$fieldVal); // $names = (new CdssXyDisease())->getNameAndAlias($fieldVal); $query = []; if($names) { $year = $this->getYear($conditionArray); if($year) { $yearArr = explode(',', $year); $query['bool']['must'][] = [ 'range' => [ 'year' => [ 'gte' => $yearArr[0] , 'lte' => $yearArr[1] ] ] ]; } /** *作者精准查询 */ if ($conditionArray[0]['select_field'] == 'author') { $query['bool']['should'][] = [ 'match_phrase' => [ 'author_list.keyword' => $fieldVal ] ]; } elseif ($conditionArray[0]['select_field'] == 'title') { $query['bool']['should'][] = [ 'match_phrase' => [ 'title' => $fieldVal ] ]; } else { foreach($names as $name) { $query['bool']['should'][] = [ 'match_phrase' => [ 'title' => $name ] ]; $query['bool']['should'][] = [ 'match_phrase' => [ 'abstract' => $name ] ]; $query['bool']['should'][] = [ 'match_phrase' => [ 'keyword' => $name ] ]; } } $query['bool']['minimum_should_match'] = 1; $params = [ 'index' => $index, 'body' => [ 'size' => $this->pagesize, 'from' => $limit, 'query' => $query , 'aggs' => [ 'keyword_list' => [ 'terms' => [ 'field'=>'keyword_list.keyword', 'order' => [ '_count' => 'desc' ], 'size' => 20 ] ], 'author_list' => [ 'terms' => [ 'field'=>'author_org_list.keyword', 'order' => [ '_count' => 'desc' ], 'size' => 20 ] ] ], 'highlight' => [ 'pre_tags' => [""], 'post_tags' => [''], 'fields' => [ 'title' => new \stdClass() , 'author' => new \stdClass() , 'keyword' => new \stdClass() , 'abstract' => new \stdClass() , 'album' => new \stdClass() , ] ], "sort" => $this->setOrder($orderField , $order), ] ]; } else { $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order); } } if(2 === $searchTag) { $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order); } $newConditionArray = $conditionArray; foreach($newConditionArray as $key => $value) { $newConditionArray[$key]['select_field_desc'] = $this->getFieldDesc($value['select_field'] , 'select_field'); $newConditionArray[$key]['select_type_desc'] = $this->getFieldDesc($value['select_type'] , 'select_type'); $newConditionArray[$key]['select_condition_desc'] = $this->getFieldDesc($value['select_condition'] , 'select_condition'); } $fieldValue = array_column($newConditionArray , 'field_value'); $singleValue = $fieldValue[0]; return [ 'params' => $params , 'content' => $newConditionArray ]; } protected function esQuery($conditionArray , $index , $limit , $orderField , $order) { /** * 高级搜索 */ foreach($conditionArray as $condition) { /** * 检测是否重名字段 */ if(stripos($condition['select_field'] , '_') != false) { $arr = explode('_', $condition['select_field']); $condition['select_field'] = $arr[0]; } if('author' === $condition['select_field']) { if(stripos($condition['field_value'] , '-') != false) { $ar = explode('-', $condition['field_value']); $condition['field_value'] = $ar[0]; } } if('and' === $condition['select_condition']) { if('year' === $condition['select_field']) { $yearArr = explode(',' , $condition['field_value']); $query['bool']['must'][] = [ 'range' => [ $condition['select_field'] => [ 'gte' => $yearArr[0] , 'lte' => $yearArr[1] , ] ] ]; } if('year' !== $condition['select_field']) { if('author' === $condition['select_field']) { /** * author 精准查询 */ $query['bool']['must'][] = [ 'match_phrase' => [ 'author_list.keyword' => $condition['field_value'] ] ]; } /** * 关键词查询 */ if('keyword' === $condition['select_field']) { /** * keyword 精准查询 */ $query['bool']['must'][] = [ 'match_phrase' => [ 'keyword_list.keyword' => $condition['field_value'] ] ]; } $query['bool']['must'][] = [ 'match_phrase' => [ $condition['select_field'] => $condition['field_value'] ] ]; } } if('or' === $condition['select_condition']) { $query['bool']['should'][] = [ 'match' => [ $condition['select_field'] => [ 'query' => $condition['field_value'], "analyzer" => "ik_max_word", "operator" => "and", "minimum_should_match" => "70%" ] ] ]; $query['bool']['should'][] = [ 'match_phrase' => [ $condition['select_field'] => [ 'query' => $condition['field_value'], "analyzer" => "ik_max_word", "slop" => 5, ] ] ]; $query['bool']['minimum_should_match'] = 1; } if('not' === $condition['select_condition']) { if('keyword' === $condition['select_field']) { $condition['select_field'] = 'keyword_list.keyword'; } $query['bool']['must_not'][] = [ 'match_phrase' => [ $condition['select_field'] => $condition['field_value'] ] ]; } if( ! $condition['select_condition']) { if('author' === $condition['select_field']) { $query['bool']['should'][] = [ 'match_phrase' => [ $condition['select_field'] => $condition['field_value'] ] ]; } else { $query['bool']['should'][] = [ 'match' => [ $condition['select_field'] => [ 'query' => $condition['field_value'], "analyzer" => "ik_max_word", "operator" => "and", "minimum_should_match" => "70%" ] ] ]; } $query['bool']['minimum_should_match'] = 1; } } //Log::info(__FUNCTION__.'query='.json_encode($query)); $params = [ 'index' => $index, 'body' => [ 'size' => $this->pagesize, 'from' => $limit, 'query' => $query , 'aggs' => [ 'keyword_list' => [ 'terms' => [ 'field'=>'keyword_list.keyword', 'order' => [ '_count' => 'desc' ], 'size' => 20 ] ], 'author_list' => [ 'terms' => [ 'field'=>'author_org_list.keyword', 'order' => [ '_count' => 'desc' ], 'size' => 20 ] ] ], 'highlight' => [ 'pre_tags' => [""], 'post_tags' => [''], 'fields' => [ 'title' => new \stdClass() , 'author' => new \stdClass() , 'keyword' => new \stdClass() , 'abstract' => new \stdClass() , 'album' => new \stdClass() , ] ], "sort" => $this->setOrder($orderField , $order), ] ]; return $params; } /** * 热点对应作者 */ public function refreshAuthors() { $value = Request::param('value') ?? ''; if( ! $value) { return $this->_json_error('参数错误!'); } $index = $this->currentLanguage(); $params = [ 'index' => $index, 'body' => [ 'size' => 30, 'from' => 0, 'query' => [ 'match' => [ 'title' => $value ] ] , ] ]; $client = $this->getEsClient(); $result = $client->search( $params ); $data = $result['hits']['hits']; foreach ($data as $value) { $newArray[] = $value['_source']; } return $this->_json_succ( $this->authors($newArray) ); } /** * 相关作者 */ protected function authors($data) { $authorOrg = array_column($data , 'author_org'); $newArray = []; foreach ($authorOrg as $key => $value) { $newArray[$key]['name'] = $value[0]['author'] ?? ''; $newArray[$key]['org'] = $value[0]['org'] ?? ''; $newArray[$key]['value'] = $key+351; $newArray[$key]['symbolSize'] = $key+40; } return $this->uniqueArr($newArray , 'name'); } /** * 文献搜索 相关作者 */ protected function relatedAuthors($data) { $newArray = []; foreach ($data['buckets'] as $key => $value){ $authorOrg = explode('#',$value['key']); $newArray[$key]['name'] = Arr::get($authorOrg,0,''); $newArray[$key]['org'] = Arr::get($authorOrg,1,''); $newArray[$key]['value'] = $value['doc_count'] + 351; $newArray[$key]['symbolSize'] = $value['doc_count']; } return $this->uniqueArr($newArray , 'name'); } /** * 二维数组某个键值唯一 */ protected function uniqueArr($arr , $key) { $newArray = []; foreach ($arr as $k => $v) { if(empty($newArray)) { $newArray[] = $arr[0][$key]; } else { if(in_array($v[$key] , $newArray)) { unset($arr[$k]); } else { $newArray[] = $v[$key]; } } } return array_slice($arr , 0 , 10 , false); } /** * 获取数组中的年份 */ protected function getYear($conditionArray) { foreach ($conditionArray as $key => $condition) { if('year' === $condition['select_field']) { return $conditionArray[$key]['field_value']; } } return ''; } protected function getConditionArrayYear($conditionArray) { foreach ($conditionArray as $key => $condition) { if($condition['select_field'] === 'year') { return $condition['field_value']; } } return ''; } /** * 研究趋势 */ protected function researchTrends($year = '' , $conditionArray = '' , $index = '') { $years = $this->getConditionArrayYear($conditionArray); $query = []; if ($years){ $year = $years; $yearArr = explode(',' , $year); foreach ($conditionArray as $key => $condition) { if($condition['select_field'] === 'year') { unset($conditionArray[$key]); } } $query['bool']['must'][] = [ 'range' => [ 'year' => [ 'gte' => $yearArr[0] , 'lte' => $yearArr[1] ] ] ]; } foreach ($conditionArray as $value) { $query['bool']['should'][] = [ 'match_phrase' => [ $value['select_field'] => $value['field_value'] ] ]; } $query['bool']['minimum_should_match'] = 1; $params = [ 'index' => $index, 'body' => [ 'size' => 1 , 'query' => $query , 'aggs' => [ 'docStat' => [ 'terms' => [ 'field' => 'year' , 'order' => [ '_key' => 'asc' ] , 'size' => 200 ] , 'aggs' => [ 'citedPerYear' => [ 'sum' => [ 'field' => 'citation_relate_count' ] ] ] ], ], 'sort' => [ [ 'year' => [ 'order' => 'desc' ] ] ] ] ]; $client = $this->getEsClient(); $result = $client->search($params); return $result['aggregations']['docStat']['buckets'] ?? []; } /** * 关联研究 */ protected function associationStudy($data) { $keywordArr = array_column($data['buckets'] , 'key'); /** * 热点词以及热点值 */ $newArray = []; foreach ($keywordArr as $kkk => $vvv) { $newArray[$kkk]['name'] = $vvv; $newArray[$kkk]['value'] = random_int(5000 , 10000); } return [ 'search' => '', 'keyword' => $newArray ]; } /** * 搜索关键词 */ protected function searchKeyword($keyword):array { if( ! $keyword) { return [ 'keyword' => '' , 'keyword_desc' => '' ]; } $keywordDesc = XyZskDisease::where("name" , "like" , "%$keyword")->whereOr('alias' , 'like' , "%$keyword%")->value('sickOverview') ?? ''; return [ 'keyword' => $keyword , 'keyword_desc' => $keywordDesc ]; } /** * 搜索历史 */ public function history() { $uid = Request::param('uid') ?? '833456167'; if( ! $uid) { $uid = 833456167; //return $this->_json_error('参数有误!'); } $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; $list = History::where('uid' , $uid) ->order('id' , 'desc') ->limit($limit , $this->pagesize) ->select() ->toArray(); if(empty($list)) { return $this->_json_succ( [] ); } return $this->_json_succ( $list ); } /** * 字段描述 */ protected function getFieldDesc($field , $tag) { if('select_field' === $tag) { $fieldDesc = [ 'title' => '标题' , 'author' => '作者' , 'abstract' => '摘要' , 'keyword' => '关键词', 'funds' => '基金' , 'references' => '参考文献' , 'doi' => 'doi' , 'album' => '期刊' , 'organization'=> '作者单位' , 'title_' => '篇名' , 'author_' => '第一作者' , 'author_o' => '通讯作者' , 'number' => '分类号' , 'references_' => '文献来源' , 'year' => '发表时间' ]; } if('select_type' === $tag) { $fieldDesc = [ 'term' => '精准' , 'match' => '模糊' ]; } if('select_condition' === $tag) { $fieldDesc = [ 'and' => 'And' , 'or' => 'Or' ]; } return $fieldDesc[$field] ?? ''; } /** * 设置排序 */ protected function setOrder($order_field = 'id' , $order = 'asc') { return [ $order_field => array( 'order' => $order ) ]; } /** * 测试 */ public function setOrderOther($orderArray = []) { if(empty($orderArray)) { return [ [ 'id' => [ 'order' => 'asc' ] ] ]; } $newOrder = []; foreach($orderArray as $key => $orders) { $newOrder[$key] = [ $orders['order_field'] => [ 'order' => $orders['order'] ] ]; } return $newOrder; } /** * 设置 fieldData */ public function setFieldData() { $index = $this->currentLanguage(); $type = Request::param('type'); $field = Request::param('field'); if( ! $index || ! $field || ! $type) { return $this->_json_error('请求错误!'); } $url = "http://121.36.74.125:9200/".$index.'/'.$type.'/_mapping'; return $this->_json_succ( $this->curl($url , $field) ); } /** * Curl */ protected function curl($url , $field) { $curl = curl_init(); // 初始化 curl_setopt($curl, CURLOPT_URL, $url); // 设置抓取的url $data = [ 'properties' => [ $field => [ 'type' => 'numeric' , // text 'fielddata' => true ] ] ]; $jsonData = json_encode($data); curl_setopt($curl, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json' ) ); curl_setopt($curl, CURLOPT_POST, 1); // 设置post方式提交 curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonData); // post提交的数据 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 设置获取的信息以文件流的形式返回,而不是直接输出。 $output = curl_exec($curl); curl_close($curl); $result = json_decode($output, true); return $result; } /** * 收藏 */ public function docCollection() { $uid = Request::param('uid') ?? '833456167'; $md5 = Request::param('md5') ?? ''; $tag = Request::param('tag') ?? ''; $title = Request::param('title') ?? ''; $pmid = Request::param('PMID') ?? ''; if(empty($uid)){ $uid = 833456167; } if(! $uid || ! $tag || ! $title) { return $this->_json_error('参数请求有误!'); } $value = ''; if ( $md5&& !$pmid){ $value = $md5; } if ( !$md5&& $pmid){ $md5 = $pmid; $value = $pmid; } $where = [ 'uid' => $uid , 'md5' => $value , ]; if('collection' === $tag) { $check = EsCollection::where($where)->find(); if($check) { if(2 == $check->status) { EsCollection::where($where)->update( [ 'status' => 1, 'title' => $title ] ); } } else { EsCollection::create( [ 'uid' => $uid , 'md5' => $md5 , 'title' => $title ] ); } } if('cancelCollection' === $tag) { EsCollection::where($where)->update( [ 'status' => 2 ] ); } return $this->_json_succ(); } /** * 我的收藏列表 */ public function myCollectionList() { $params = input('post.'); $uid = $params['uid'] ?? '833456167'; /** * 搜索参数 */ $search = $params['search'] ?? ''; $tag = $params['tag'] ?? ''; $where = []; /** * 文献标题搜索 */ if( $search ) { $where[] = ['title' , 'like' , "%$search%"]; } /** * 文献标签搜索 */ if( $tag ) { $where[] = ['tags' , 'like' , "%$tag%"]; } $page = $params['page'] ?? 1; $limit = ($page - 1) * $this->pagesize; $myEsCollectionList = EsCollection::where($where)->where([ 'uid' => $uid , 'status' => 1 ])->limit($limit , $this->pagesize)->select()->toArray(); if( ! $myEsCollectionList ) { return $this->_json_error('暂无收藏数据!'); } /** * 获取收藏文献数据(es) */ $client = $this->getEsClient(); $uniqIdArr = array_column($myEsCollectionList , 'md5'); foreach($uniqIdArr as $uniqId) { $params = [ 'index' => $this->index, 'body' => [ 'query' => [ 'bool' => [ 'should' => [ [ "constant_score" => [ "filter" => [ "match" => [ 'uniq_id' => $uniqId ] ] ] ], [ "constant_score" => [ "filter" => [ "match" => [ 'PMID' => $uniqId ] ] ] ] ] ] ], ] ]; /** * 结果集 */ $result[] = $client->search($params); } /** * 获取source集合 */ foreach ($result as $k => $v) { $hits[] = $result[$k]['hits']['hits'][0] ?? []; } if( ! $hits) { $sourceArr = []; } else { /** * 将mysql收藏文献标签(tags)追加到es数据 */ $sourceArr = array_column($hits , '_source'); foreach ($sourceArr as $kk => $vv) { foreach ($myEsCollectionList as $vvv) { if($vv['uniq_id'] === $vvv['md5']) { $sourceArr[$kk]['tags'] = $vvv['tags']; } } $sourceArr[$kk]['is_collection'] = $this->checkIsCollectionDoc($uid , $vv['uniq_id']); $sourceArr[$kk]['click_count'] = ClickCount::where('md5' , $vv['uniq_id'])->value('click_count') ?? 0; } } /** * 收藏文献标签集合 */ $newTagList = []; foreach ($myEsCollectionList as $tkey => $tval) { $newTagList[] = explode(',' , $tval['tags']); } $newTagList = array_filter($this->mergeArray($newTagList)); return $this->_json_succ( [ 'tags_list' => $newTagList , 'list' => $sourceArr ] ); } /** * 合并二维数组下的多个一维数组 */ protected function mergeArray($arr) { return call_user_func_array('array_merge' , $arr); } /** * 添加收藏标签 * @return */ public function docCollectionTags() { $uid = Request::param('uid') ?? '833456167'; $md5 = Request::param('md5') ?? ''; $tags = Request::param('tags') ?? []; if( ! $uid || ! $md5 || empty($tags)) { return $this->_json_error('参数请求有误!'); } $collection = EsCollection::where([ 'uid' => $uid , 'md5' => $md5 , 'status' => 1 , ])->find(); if ( ! $collection ) { return $this->_json_error('文献不存在'); } $collection->tags = implode(',' , $tags); $collection->save(); return $this->_json_succ(); } /** * 列表返回统一封装 */ protected function dataAssemble($uid , $total , $data , $otherOrderField = '' , $otherOrder = ''):array { if(empty($data)) { return []; } // foreach($data as $key => $value) { // if(stripos($value['abstract'] , '<正>') !== false) { // $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']); // } // /** // * 文献点击量 是否收藏 // */ // $data[$key]['is_collection'] = $this->checkIsCollectionDoc($uid , $value['uniq_id']); // $data[$key]['click_count'] = ClickCount::where('md5' , $value['uniq_id'])->value('click_count') ?? 0; // } $md5Arr = []; /** * 处理文献中带 <正> */ foreach($data as $key => $value) { if(isset($value['abstract'])) { $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']); } if(isset($value['periodical_md5'])) { $md5Arr[] = $value['periodical_md5']; } } //文献 收藏 点击量 $md5Res = EsCollection::where(['uid' => $uid])->whereIn('md5', $md5Arr)->select()->toArray(); $clickCountRes = ClickCount::whereIn('md5', $md5Arr)->select()->toArray(); foreach ($data as $key => $value) { $data[$key]['is_collection'] = 2; $data[$key]['click_count'] = 0; if (isset($value['periodical_md5'])) { if ($collectionKey = array_search($value['periodical_md5'], array_column($md5Res, 'md5'))) { if ($md5Res[$collectionKey]['status'] != 2) { $data[$key]['is_collection'] = 1; } } if ($clickCountKey = array_search($value['periodical_md5'], array_column($clickCountRes, 'md5'))) { $data[$key]['click_count'] = $clickCountRes[$clickCountKey]['click_count']; } } } /** * 点击量动态数组排序 */ if('click_count' === $otherOrderField) { $click_count = array_column($data , 'click_count'); $otherOrder = 'asc' === $otherOrder ? SORT_ASC : SORT_DESC; array_multisort($click_count , $otherOrder , $data); } return [ 'total' => $total, 'total_page' => ceil($total / $this->pagesize), 'data' => $data ]; } /** * 用户是否收藏文献 * 1.已收藏 2.未收藏 */ protected function checkIsCollectionDoc($uid , $uniq_id) { $check = EsCollection::where(['uid' => $uid , 'md5' => $uniq_id])->find(); if( ! $check || 2 == $check->status) { return 2; } return 1; } /** * 换一批 */ public function randomDoc() { $tag = Request::param('tag') ?? $this->index; $uid = Request::param('uid') ?? '833456167'; $index = $tag; $field = Request::param('field') ?? 'title , periodical_md5'; $page = Request::param('page') ?? 1; $limit = ($page - 1) * 10; //$index = $this->currentLanguage(); $index = 'document_zh'; $params = [ 'index' => $index, 'body' => [ 'from' => $limit, 'size' => 10, 'query' => [ 'match_all' => (object)[] , // 查询全部 ], "_source" => ['title' , 'periodical_md5' , 'uniq_id'], // 获取制定字段 //"sort" => $this->setOrder('year' , 'desc'), ], ]; $result = $this->esCommonGetData($params); return $this->_json_succ($result); } /** * 相关推荐 * * @param $tag string 模块标识 (学科分析 | 学者分析 | 期刊分析) * @param $value string 分析值 * @param $type string 类型 (最新 | 最高) * @return Json */ public function relationRecommend() { $org = Request::param('org') ?? ''; $tag = Request::param('tag') ?? ''; $value = Request::param('value') ?? ''; $type = Request::param('type') ?? 'highest'; if( ! $tag || ! $value || ! $type) { return $this->_json_error('请求参数有误!'); } $page = Request::param('page') ?? 1; $limit = ($page - 1) * $this->pagesize; if('department' === $tag) { $selectField = 'title'; $selectType = 'match_phrase'; } if('album' === $tag) { $selectField = 'album.keyword'; $selectType = 'match'; } if('highest' === $type) { $orderField = 'citation_relate_count'; $order = 'desc'; } if('newest' === $type) { $orderField = 'year'; $order = 'desc'; } if('author' === $tag) { $query = [ 'bool' => [ 'must' => [ [ 'nested' => [ 'path' => 'author_org', 'query' => [ 'bool' => [ 'must' => [ [ 'match_phrase' => [ 'author_org.author' => $value ] ], [ 'match_phrase' => [ 'author_org.org' => $org ] ] ] ] ] ] ], [ 'match_phrase' => [ 'author' => $value ] ], [ 'range' => [ 'year' => [ 'gte' => 2002 , 'lte' => 2040 ] ] ] ] ] ]; }else{ $query = [ 'bool' => [ 'must' => [ [ $selectType => [ $selectField => $value ] ], [ 'range' => [ 'year' => [ 'gte' => 2002 , 'lte' => 2040 ] ] ] ] ] ]; } $index = $this->currentLanguage(); //$source = ["author" , "title" , "year" , "citation_relate_count" , "album" , "periodical_md5" , "author_list"]; $params = [ 'index' => $index , 'from' => $limit , 'size' => $this->pagesize, 'body' => [ 'query' => $query, 'highlight' => [ 'pre_tags' => [""], 'post_tags' => [''], 'fields' => [ 'author' => new \stdClass() , ] ], 'sort' => $this->setOrder($orderField , $order) ] ]; $client = $this->getEsClient(); $esData = $client->search( $params ); $result = $esData['hits']['hits']; $data = $result; /** * 关键词高亮 */ foreach($data as $key => $value) { if(isset($value['highlight']['author']) ) { $authorList = explode(";" , $value['highlight']['author'][0]); } else { $authorList = $data[$key]['_source']['author_list']; } $data[$key]['_source']['author_list'] = $authorList; } return $this->_json_succ( [ 'total' => $esData['hits']['total'], 'total_page' => ceil($esData['hits']['total'] / $this->pagesize) , 'list' => array_column($data , '_source') ] ); } /** * 清除 */ public function clear() { $uid = Request::param('uid') ?? '833456167'; $id = Request::param('id') ?? ''; $tag = Request::param('tag') ?? ''; if(! $uid || ! $tag) { return $this->_json_error('请求有误!'); } if('clear' === $tag) { History::where('uid' , $uid)->delete(); } else { if($id) { History::where('id' , $id)->delete(); } } return $this->_json_succ(); } }