EsDocument.php 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954
  1. <?php
  2. namespace app\controller;
  3. use app\model\CdssXyDisease;
  4. use app\model\ClickCount;
  5. use app\model\EsCollection;
  6. use app\model\XyZskDisease;
  7. use think\facade\Session;
  8. use think\helper\Arr;
  9. use think\response\Json;
  10. use think\facade\Request;
  11. use app\model\History;
  12. /**
  13. * Es文献类(科研探索)
  14. */
  15. class EsDocument extends CommonEsController
  16. {
  17. /**
  18. * 测试方法
  19. */
  20. public function test()
  21. {
  22. $orderArray = [
  23. [
  24. 'order_field' => 'mark',
  25. 'order' => 'desc'
  26. ] ,
  27. [
  28. 'order_field' => 'year',
  29. 'order' => 'desc'
  30. ]
  31. ];
  32. return $this->_json_succ(
  33. $this->setOrderOther($orderArray)
  34. );
  35. }
  36. /**
  37. * 设置语言
  38. */
  39. public function setLanguage()
  40. {
  41. $language = Request::param('language') ?? 'document_zh';
  42. Session::set('language' , $language);
  43. return $this->_json_succ(
  44. [
  45. 'language' => $language
  46. ]
  47. );
  48. }
  49. /**
  50. * 搜索提示
  51. */
  52. public function searchTip()
  53. {
  54. $search = Request::param('search') ?? '';
  55. if( ! $search) {
  56. return $this->_json_error('请求有误!');
  57. }
  58. $field = Request::param('field') ?? 'name';
  59. $diseases = CdssXyDisease::field($field)
  60. ->where('name' , 'like' , "%$search%")
  61. ->select()
  62. ->toArray() ?? [];
  63. $diseaseArr = empty($diseases) ? [] : array_values(array_filter(array_column($diseases , $field)));
  64. return $this->_json_succ(
  65. $diseaseArr
  66. );
  67. }
  68. /**
  69. * 普通检索| 疾病别名
  70. */
  71. public function singleSearchRecommendDisease()
  72. {
  73. $keyword = Request::param('search') ?? '';
  74. if( ! $keyword) {
  75. return $this->_json_error(
  76. '请求参数有误!'
  77. );
  78. }
  79. $diseases = (new CdssXyDisease())->getNameAndAlias($keyword);
  80. return $this->_json_succ(
  81. $diseases
  82. );
  83. }
  84. /**
  85. * 高级检索推荐疾病 | 疾病别名
  86. */
  87. public function searchRecommendDisease()
  88. {
  89. $keyword = Request::param('keyword') ?? '';
  90. if( ! $keyword) {
  91. return $this->_json_error('请求有误!');
  92. }
  93. $disease = CdssXyDisease::field('name , alias')->where('name' , $keyword)->find();
  94. if(empty($disease)) {
  95. $disease = CdssXyDisease::field('name , alias')->whereOr('alias' , 'like' ,"%$keyword%")->find();
  96. }
  97. $name = $disease->name;
  98. $alias = $disease->alias;
  99. if(stripos($alias , ';') !== false) {
  100. $newArray[] = $name;
  101. $aliasArr = explode(';' , $alias);
  102. $newArray = array_merge($newArray, $aliasArr);
  103. } elseif(stripos($alias , ';') !== false) {
  104. $newArray[] = $name;
  105. $aliasArr = explode(';' , $alias);
  106. $newArray = array_merge($newArray, $aliasArr);
  107. } else {
  108. $newArray[] = $name;
  109. $newArray[] = $alias;
  110. }
  111. $diseases = CdssXyDisease::field('name')->whereOr('name' , 'like' ,"%$keyword%")->select()->toArray();
  112. $diseasesArr = array_column($diseases , 'name') ?? [];
  113. return $this->_json_succ(
  114. array_unique(array_merge($newArray, $diseasesArr))
  115. );
  116. }
  117. /**
  118. * 文献首页
  119. *
  120. * @param $document string
  121. * @param $field string
  122. * @param $page int
  123. * @return Json
  124. */
  125. public function index():Json
  126. {
  127. $uid = Request::param('uid') ?? '833456167';
  128. $field = Request::param('field') ?? '*';
  129. $page = Request::param('page') ?? 1;
  130. $limit = ($page - 1) * $this->pagesize;
  131. //$index = $this->currentLanguage();
  132. $index = 'document_zh';
  133. $params = [
  134. 'index' => $index,
  135. 'body' => [
  136. 'from' => $limit,
  137. 'size' => $this->pagesize,
  138. 'query' => [
  139. 'match_all' => (object)[] , // 查询全部
  140. ],
  141. "_source" => $field, // 获取制定字段
  142. //"sort" => $this->setOrderOther();
  143. ],
  144. "preference" => "_primary_first"
  145. ];
  146. //print_r($params);die;
  147. $result = $this->esCommonGetData($params);
  148. return $this->_json_succ(
  149. $this->dataAssemble(
  150. $uid , $result['total'] , $result['data']
  151. )
  152. );
  153. }
  154. /**
  155. * 文献详情
  156. */
  157. public function esDocumentDetail()
  158. {
  159. $periodicalMd5 = Request::param('periodical_md5') ?? '';
  160. $uniqId = Request::param('uniq_id') ?? '';
  161. $pmid = Request::param('PMID') ?? '';
  162. if( ! $periodicalMd5 && ! $uniqId && ! $pmid) {
  163. return $this->_json_error('请求参数有误!');
  164. }
  165. $index = 'document_en,document_zh';
  166. if($periodicalMd5 || ($periodicalMd5 && $uniqId)) {
  167. $field = 'periodical_md5';
  168. $value = $periodicalMd5;
  169. }
  170. if($uniqId && ! $periodicalMd5) {
  171. $field = 'uniq_id';
  172. $value = $uniqId;
  173. }
  174. if ($pmid && ! $uniqId) {
  175. $field = 'PMID';
  176. $value = $pmid;
  177. }
  178. $uid = Request::param('uid') ?? '833456167';
  179. $params = [
  180. 'index' => $index,
  181. 'body' => [
  182. 'query' => [
  183. "constant_score" => [
  184. "filter" => [
  185. "term" => [
  186. $field => $value
  187. ]
  188. ],
  189. ],
  190. ],
  191. ]
  192. ];
  193. $client = $this->getEsClient();
  194. $result = $client->search($params);
  195. if( 0 == $result['hits']['total']) {
  196. return $this->_json_error('未查询到数据!');
  197. }
  198. $detail = $result['hits']['hits'][0]['_source'] ?? [];
  199. $detail['is_collection'] = EsCollection::checkIsCollection($uid , $value);
  200. $detail['click_count'] = ClickCount::where('md5' , $value)->value('click_count');
  201. $titleArr = [
  202. 'N1站淋巴结检出数目对pT1~3N0M0非小细胞肺癌患者预后的影响' ,
  203. '滋燥养荣颗粒治疗非小细胞肺癌EGFRIs相关皮肤干燥症阴虚血燥证有效性及安全性的长期随访研究',
  204. '胸腔镜肺叶切除术与肺段切除术治疗T1bN0M0 期非小细胞肺癌的回顾性队列研究'
  205. ];
  206. //if(in_array($detail['title'] , $titleArr)) {
  207. // $detail['pdf_url'] = 'https://jm.jiankangche.cn/zsk/pdf/202302082310.pdf';
  208. //} else {
  209. // $detail['pdf_url'] = $this->checkDocPdfIsExist($detail['pdf_name'] ?? '');
  210. //}
  211. $datail['pdf_url'] = '';
  212. ClickCount::docClickCount($value);
  213. return $this->_json_succ(
  214. $detail
  215. );
  216. }
  217. /**
  218. * 检测pdf文档地址是否可访问
  219. */
  220. private function checkDocPdfIsExist($pdf_name = '')
  221. {
  222. if( ! $pdf_name ) {
  223. return "";
  224. }
  225. $url = 'https://jm.jiankangche.cn/zsk/pdf/'.$pdf_name;
  226. $check = get_headers($url);
  227. return stripos($check[0] , '200') !== false ? $url : "";
  228. }
  229. /**
  230. * 相关文献
  231. */
  232. public function getDocumentByTag()
  233. {
  234. $title = Request::param('title') ?? '';
  235. $tag = Request::param('tag') ?? 'similarity';
  236. $uid = Request::param('uid') ?? '833456167';
  237. if( ! $title || ! $tag ) {
  238. return $this->_json_error('请求错误!');
  239. }
  240. $page = Request::param('page') ?? 1;
  241. $limit = ($page - 1) * $this->pagesize;
  242. $index = $this->currentLanguage();
  243. $params = [
  244. 'index' => $index,
  245. 'body' => [
  246. 'size' => $this->pagesize,
  247. 'from' => $limit,
  248. 'query' => [
  249. "match"=>[
  250. 'title' => [
  251. 'query' => $title,
  252. 'boost' => 3, // 权重
  253. ],
  254. ],
  255. ],
  256. ]
  257. ];
  258. $result = $this->esCommonGetData($params);
  259. return $this->_json_succ(
  260. $this->dataAssemble($uid , $result['total'] , $result['data'])
  261. );
  262. }
  263. /**
  264. * 参考文献
  265. */
  266. public function references()
  267. {
  268. }
  269. /**
  270. * 最高 | 最新 期刊
  271. *
  272. * @param $tag string 标识
  273. * @param $page int 分页
  274. * @return Json
  275. */
  276. public function getAlbumByTag():Json
  277. {
  278. $tag = Request::param('tag') ?? 'highest';
  279. if( ! $tag) {
  280. return $this->_json_error('请求参数有误!');
  281. }
  282. /**
  283. * 最高
  284. */
  285. if('highest' === $tag) {
  286. $orderField = 'total_citations_number.keyword';
  287. $order = 'desc';
  288. }
  289. /**
  290. * 最新
  291. */
  292. if('recently' === $tag) {
  293. $orderField = 'first_time.keyword';
  294. $order = 'desc';
  295. }
  296. $page = Request::param('page') ?? 1;
  297. $limit = ($page - 1) * $this->pagesize;
  298. $index = $this->currentLanguage();
  299. $albumIndex = 'document_zh' === $index ? 'album' : 'album_en';
  300. $params = [
  301. 'index' => $albumIndex,
  302. 'body' => [
  303. 'from' => $limit,
  304. 'size' => $this->pagesize,
  305. 'query' => [
  306. 'match_all' => (object)[] , // 查询全部
  307. ],
  308. //"_source" => $field, // 获取制定字段
  309. "sort" => $this->setOrder($orderField , $order),
  310. ],
  311. ];
  312. return $this->_json_succ(
  313. $this->esCommonGetData($params)
  314. );
  315. }
  316. /**
  317. * 搜索
  318. */
  319. public function conditionFilter()
  320. {
  321. $searchType = Request::param('search_type') ?? 'many';
  322. if( ! $searchType ) {
  323. $this->_json_error('参数请求错误!');
  324. }
  325. /**
  326. * 排序
  327. */
  328. $orderField = Request::param('order_field') ?? 'year';
  329. $order = Request::param('order') ?? 'desc';
  330. $searchTag = Request::param('search_tag') ?? 2;
  331. $uid = Request::param('uid') ?? '833456167';
  332. /**
  333. * 点击量排序
  334. */
  335. if('click_count' === $orderField) {
  336. $orderField = 'year';
  337. $otherOrderField = 'click_count';
  338. $otherOrder = $order;
  339. } else {
  340. $otherOrderField = '';
  341. $otherOrder = '';
  342. }
  343. /**
  344. * 年份筛选
  345. */
  346. $year = Request::param('year') ?? '';
  347. /**
  348. * 高级搜索数组
  349. */
  350. $conditionArray = Request::param('condition') ?? '';
  351. if( ! $conditionArray ) {
  352. $this->_json_error('搜索条件有误!');
  353. }
  354. foreach($conditionArray as $k => $v) {
  355. if( ! $v['field_value']) {
  356. unset($conditionArray[$k]);
  357. }
  358. if ($searchType === 1){
  359. //有别名的情况跳过
  360. continue;
  361. }
  362. /**
  363. * 标题搜索 匹配英文
  364. */
  365. if ($v['select_field'] == 'title'){
  366. //$translated_field_value = $this->translate($v['field_value']);
  367. $translated_field_value = null;
  368. $conditionArray[$k] = [
  369. "select_field"=> "title",
  370. "field_value" => $v['field_value'],
  371. "select_type"=> "match",
  372. "select_condition"=> "or"
  373. ];
  374. if ($translated_field_value){
  375. $conditionArray[] = [
  376. "select_field"=> "title",
  377. "field_value"=>$translated_field_value,
  378. "select_type"=> "match",
  379. "select_condition"=> "or"
  380. ];
  381. }
  382. }
  383. /**
  384. * 主题搜索 匹配英文
  385. */
  386. if ($v['select_field'] == 'theme'){
  387. $conditionArray[] = [
  388. "select_field"=> "title",
  389. "field_value" => $v['field_value'],
  390. "select_type"=> "match",
  391. "select_condition"=> "or"
  392. ];
  393. $conditionArray[] = [
  394. "select_field"=> "abstract",
  395. "field_value" => $v['field_value'],
  396. "select_type"=> "match",
  397. "select_condition"=> "or"
  398. ];
  399. $conditionArray[] = [
  400. "select_field"=> "keyword",
  401. "field_value" => $v['field_value'],
  402. "select_type"=> "match",
  403. "select_condition"=> "or"
  404. ];
  405. //$translated_field_value = $this->translate($v['field_value']);
  406. $translated_field_value = null;
  407. if ($translated_field_value){
  408. $conditionArray[] = [
  409. "select_field"=> "title",
  410. "field_value"=>$translated_field_value,
  411. "select_type"=> "match",
  412. "select_condition"=> "or"
  413. ];
  414. $conditionArray[] = [
  415. "select_field"=> "abstract",
  416. "field_value"=>$translated_field_value,
  417. "select_type"=> "match",
  418. "select_condition"=> "or"
  419. ];
  420. $conditionArray[] = [
  421. "select_field"=> "keyword",
  422. "field_value"=>$translated_field_value,
  423. "select_type"=> "match",
  424. "select_condition"=> "or"
  425. ];
  426. }
  427. }
  428. }
  429. /**
  430. * 连接es
  431. */
  432. $client = $this->getEsClient();
  433. /**
  434. * 获取查询结果
  435. */
  436. $page = Request::param('page') ?? 1;
  437. $limit = ($page - 1) * $this->pagesize;
  438. /**
  439. * 当前索引名称
  440. */
  441. // $index = $this->currentLanguage();
  442. $index = 'document_zh,document_en';
  443. /**
  444. * 组装es-query
  445. */
  446. $array = $this->combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag , $year);
  447. //dd(json_encode($array['params'],JSON_UNESCAPED_UNICODE));
  448. $result = $client->search(
  449. $array['params']
  450. );
  451. /**
  452. * 数据以及数据总数
  453. */
  454. $total = $result['hits']['total'];
  455. if(0 == $total) {
  456. return $this->_json_error('未检索到结果!');
  457. }
  458. $data = $result['hits']['hits'];
  459. /**
  460. * 特殊搜索处理 (非小细胞肺癌)
  461. */
  462. $fieldValueArr = array_column($conditionArray , 'field_value');
  463. $fieldValue = '非小细胞肺癌';
  464. if(in_array($fieldValue , $fieldValueArr)) {
  465. $data[0] = $this->docDetail($index);
  466. }
  467. $totalPage = ceil($total / $this->pagesize);
  468. /**
  469. * 关键词高亮
  470. */
  471. foreach($data as $key => $value) {
  472. if(isset($value['highlight']['author']) ) {
  473. $authorList = explode(";" , $value['highlight']['author'][0]);
  474. } else {
  475. $authorList = $data[$key]['_source']['author_list'] ?? '';
  476. }
  477. if(isset($value['highlight']['keyword']) ) {
  478. $keywordList = explode(";" , $value['highlight']['keyword'][0]);
  479. } else {
  480. $keywordList = $data[$key]['_source']['keyword_list'] ?? '';
  481. }
  482. $data[$key]['_source']['title'] = isset($value['highlight']['title']) ? $value['highlight']['title'][0] : $data[$key]['_source']['title'];
  483. $data[$key]['_source']['abstract'] = isset($value['highlight']['abstract']) ? $value['highlight']['abstract'][0] : $data[$key]['_source']['abstract'];
  484. $data[$key]['_source']['author_list'] = $authorList;
  485. $data[$key]['_source']['keyword_list'] = $keywordList;
  486. }
  487. if('many' === $searchType) {
  488. /**
  489. * 记录查询历史
  490. */
  491. $content = $array['content'] ?? '';
  492. $searchDesc = '';
  493. $searchConditions = '';
  494. $countContent = count($content);
  495. foreach ($content as $k => $v) {
  496. if($k == ($countContent - 1)) {
  497. $selectCondition = '';
  498. } else {
  499. $selectCondition = $content[$k+1]['select_condition'];
  500. }
  501. $searchDesc.= '('.$v['select_field_desc'] . '=' . $v['field_value'].')' . $selectCondition . ' ';
  502. $searchConditions.= $v['select_condition'] . ' ';
  503. }
  504. $checkIsExistSearchHistory = History::where(
  505. [
  506. 'uid' => $uid ,
  507. 'search_desc' => $searchDesc
  508. ]
  509. )->find();
  510. if( ! $checkIsExistSearchHistory) {
  511. History::create(
  512. [
  513. 'uid' => $uid ,
  514. 'content' => json_encode($array['content'] ?? '') ,
  515. 'tag' => $searchTag ,
  516. 'search_doc_count' => $total ,
  517. 'search_desc' => $searchDesc ,
  518. 'search_conditions' => $searchConditions
  519. ]
  520. );
  521. }
  522. }
  523. $newArray = [];
  524. /**
  525. * 获取实际返回数据源
  526. */
  527. foreach ($data as $value) {
  528. $newArray[] = $value['_source'];
  529. }
  530. $combineData = $this->dataAssemble($uid , $total, $newArray , $otherOrderField , $otherOrder);
  531. /**
  532. * 相关作者
  533. */
  534. $combineData['authors'] = $this->relatedAuthors($result['aggregations']['author_list']);
  535. /**
  536. * 搜索关键词
  537. */
  538. $combineData['keyword'] = $this->searchKeyword($conditionArray[0]['field_value'] ?? '');
  539. /**
  540. * 研究趋势
  541. */
  542. $combineData['research_trends'] = $this->researchTrends($year , $conditionArray , $index);
  543. /**
  544. * 关联研究
  545. */
  546. $combineData['associationStudy'] = $this->associationStudy($result['aggregations']['keyword_list']);
  547. $combineData['total_page'] = $totalPage;
  548. $combineData['total'] = $total;
  549. return $this->_json_succ(
  550. $combineData
  551. );
  552. }
  553. public function translate($text)
  554. {
  555. $url = config('translate.request_url.get_profile_url');
  556. $response = $this->curlGetRequest($url);
  557. if( ! $response) {
  558. return false;
  559. }
  560. $profile = json_decode($response , true) ?? '';
  561. if( ! $profile) {
  562. return $this->_json_error('系统繁忙,稍候再试!');
  563. }
  564. /**
  565. * 团队ID
  566. */
  567. $teamId = $profile['data']['member'][0]['team_id'];
  568. $url = config('translate.request_url.text_translate_url');
  569. $realRequestUrl = $url.$teamId;
  570. if (preg_match("/^[^\x80-\xff]+$/", $text)){
  571. $source = 'en';
  572. $target = 'zh';
  573. }else{
  574. $source = 'zh';
  575. $target = 'en';
  576. }
  577. /**
  578. * 请求参数
  579. */
  580. $requestParams = [
  581. "source" => $source,
  582. "target" => $target,
  583. "domain" => "medical" ,
  584. 'lines' => [
  585. [
  586. 'id' => 0 ,
  587. 'text' => $text
  588. ]
  589. ]
  590. ];
  591. $response = $this->curlPostRequest($realRequestUrl , $requestParams , '9b4a6c0f23f50eb6530d6cc4a03b0e96a2f051db');
  592. $arr = json_decode($response , true);
  593. $data = $arr['data'];
  594. return $data[0]['text'] ?? '';
  595. }
  596. /**
  597. * 获取详情
  598. */
  599. protected function docDetail($index)
  600. {
  601. $params = [
  602. 'index' => $index,
  603. 'body' => [
  604. 'query' => [
  605. "constant_score" => [
  606. "filter" => [
  607. "term" => [
  608. 'uniq_id' => '001'
  609. ]
  610. ],
  611. ],
  612. ],
  613. ]
  614. ];
  615. $client = $this->getEsClient();
  616. $result = $client->search($params);
  617. return $result['hits']['hits'][0] ?? [];
  618. }
  619. /**
  620. * 组装条件
  621. */
  622. protected function combineCondition($limit , $conditionArray , $searchType , $uid , $orderField , $order , $index , $searchTag)
  623. {
  624. if(1 === $searchTag) {
  625. /**
  626. * 普通检索 有别名和标准名称情况
  627. */
  628. $fieldVal = $conditionArray[0]['field_value'];
  629. $names = explode(',',$fieldVal);
  630. // $names = (new CdssXyDisease())->getNameAndAlias($fieldVal);
  631. $query = [];
  632. if($names) {
  633. $year = $this->getYear($conditionArray);
  634. if($year) {
  635. $yearArr = explode(',', $year);
  636. $query['bool']['must'][] = [
  637. 'range' => [
  638. 'year' => [
  639. 'gte' => $yearArr[0] ,
  640. 'lte' => $yearArr[1]
  641. ]
  642. ]
  643. ];
  644. }
  645. /**
  646. *作者精准查询
  647. */
  648. if ($conditionArray[0]['select_field'] == 'author') {
  649. $query['bool']['should'][] = [
  650. 'match_phrase' => [
  651. 'author_list.keyword' => $fieldVal
  652. ]
  653. ];
  654. } elseif ($conditionArray[0]['select_field'] == 'title') {
  655. $query['bool']['should'][] = [
  656. 'match_phrase' => [
  657. 'title' => $fieldVal
  658. ]
  659. ];
  660. } else {
  661. foreach($names as $name) {
  662. $query['bool']['should'][] = [
  663. 'match_phrase' => [
  664. 'title' => $name
  665. ]
  666. ];
  667. $query['bool']['should'][] = [
  668. 'match_phrase' => [
  669. 'abstract' => $name
  670. ]
  671. ];
  672. $query['bool']['should'][] = [
  673. 'match_phrase' => [
  674. 'keyword' => $name
  675. ]
  676. ];
  677. }
  678. }
  679. $query['bool']['minimum_should_match'] = 1;
  680. $params = [
  681. 'index' => $index,
  682. 'body' => [
  683. 'size' => $this->pagesize,
  684. 'from' => $limit,
  685. 'query' => $query ,
  686. 'aggs' => [
  687. 'keyword_list' => [
  688. 'terms' => [
  689. 'field'=>'keyword_list.keyword',
  690. 'order' => [
  691. '_count' => 'desc'
  692. ],
  693. 'size' => 20
  694. ]
  695. ],
  696. 'author_list' => [
  697. 'terms' => [
  698. 'field'=>'author_org_list.keyword',
  699. 'order' => [
  700. '_count' => 'desc'
  701. ],
  702. 'size' => 20
  703. ]
  704. ]
  705. ],
  706. 'highlight' => [
  707. 'pre_tags' => ["<font color='red'>"],
  708. 'post_tags' => ['</font>'],
  709. 'fields' => [
  710. 'title' => new \stdClass() ,
  711. 'author' => new \stdClass() ,
  712. 'keyword' => new \stdClass() ,
  713. 'abstract' => new \stdClass() ,
  714. 'album' => new \stdClass() ,
  715. ]
  716. ],
  717. "sort" => $this->setOrder($orderField , $order),
  718. ]
  719. ];
  720. } else {
  721. $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order);
  722. }
  723. }
  724. if(2 === $searchTag) {
  725. $params = $this->esQuery($conditionArray , $index , $limit , $orderField , $order);
  726. }
  727. $newConditionArray = $conditionArray;
  728. foreach($newConditionArray as $key => $value) {
  729. $newConditionArray[$key]['select_field_desc'] = $this->getFieldDesc($value['select_field'] , 'select_field');
  730. $newConditionArray[$key]['select_type_desc'] = $this->getFieldDesc($value['select_type'] , 'select_type');
  731. $newConditionArray[$key]['select_condition_desc'] = $this->getFieldDesc($value['select_condition'] , 'select_condition');
  732. }
  733. $fieldValue = array_column($newConditionArray , 'field_value');
  734. $singleValue = $fieldValue[0];
  735. return [
  736. 'params' => $params ,
  737. 'content' => $newConditionArray
  738. ];
  739. }
  740. protected function esQuery($conditionArray , $index , $limit , $orderField , $order)
  741. {
  742. /**
  743. * 高级搜索
  744. */
  745. foreach($conditionArray as $condition) {
  746. /**
  747. * 检测是否重名字段
  748. */
  749. if(stripos($condition['select_field'] , '_') != false) {
  750. $arr = explode('_', $condition['select_field']);
  751. $condition['select_field'] = $arr[0];
  752. }
  753. if('author' === $condition['select_field']) {
  754. if(stripos($condition['field_value'] , '-') != false) {
  755. $ar = explode('-', $condition['field_value']);
  756. $condition['field_value'] = $ar[0];
  757. }
  758. }
  759. if('and' === $condition['select_condition']) {
  760. if('year' === $condition['select_field']) {
  761. $yearArr = explode(',' , $condition['field_value']);
  762. $query['bool']['must'][] = [
  763. 'range' => [
  764. $condition['select_field'] => [
  765. 'gte' => $yearArr[0] ,
  766. 'lte' => $yearArr[1] ,
  767. ]
  768. ]
  769. ];
  770. }
  771. if('year' !== $condition['select_field']) {
  772. if('author' === $condition['select_field']) {
  773. /**
  774. * author 精准查询
  775. */
  776. $query['bool']['must'][] = [
  777. 'match_phrase' => [
  778. 'author_list.keyword' => $condition['field_value']
  779. ]
  780. ];
  781. }
  782. /**
  783. * 关键词查询
  784. */
  785. if('keyword' === $condition['select_field']) {
  786. /**
  787. * keyword 精准查询
  788. */
  789. $query['bool']['must'][] = [
  790. 'match_phrase' => [
  791. 'keyword_list.keyword' => $condition['field_value']
  792. ]
  793. ];
  794. }
  795. $query['bool']['must'][] = [
  796. 'match_phrase' => [
  797. $condition['select_field'] => $condition['field_value']
  798. ]
  799. ];
  800. }
  801. }
  802. if('or' === $condition['select_condition']) {
  803. $query['bool']['should'][] = [
  804. 'match' => [
  805. $condition['select_field'] => [
  806. 'query' => $condition['field_value'],
  807. "analyzer" => "ik_max_word",
  808. "operator" => "and",
  809. "minimum_should_match" => "70%"
  810. ]
  811. ]
  812. ];
  813. $query['bool']['should'][] = [
  814. 'match_phrase' => [
  815. $condition['select_field'] => [
  816. 'query' => $condition['field_value'],
  817. "analyzer" => "ik_max_word",
  818. "slop" => 5,
  819. ]
  820. ]
  821. ];
  822. $query['bool']['minimum_should_match'] = 1;
  823. }
  824. if('not' === $condition['select_condition']) {
  825. if('keyword' === $condition['select_field']) {
  826. $condition['select_field'] = 'keyword_list.keyword';
  827. }
  828. $query['bool']['must_not'][] = [
  829. 'match_phrase' => [
  830. $condition['select_field'] => $condition['field_value']
  831. ]
  832. ];
  833. }
  834. if( ! $condition['select_condition']) {
  835. if('author' === $condition['select_field']) {
  836. $query['bool']['should'][] = [
  837. 'match_phrase' => [
  838. $condition['select_field'] => $condition['field_value']
  839. ]
  840. ];
  841. } else {
  842. $query['bool']['should'][] = [
  843. 'match' => [
  844. $condition['select_field'] => [
  845. 'query' => $condition['field_value'],
  846. "analyzer" => "ik_max_word",
  847. "operator" => "and",
  848. "minimum_should_match" => "70%"
  849. ]
  850. ]
  851. ];
  852. }
  853. $query['bool']['minimum_should_match'] = 1;
  854. }
  855. }
  856. //Log::info(__FUNCTION__.'query='.json_encode($query));
  857. $params = [
  858. 'index' => $index,
  859. 'body' => [
  860. 'size' => $this->pagesize,
  861. 'from' => $limit,
  862. 'query' => $query ,
  863. 'aggs' => [
  864. 'keyword_list' => [
  865. 'terms' => [
  866. 'field'=>'keyword_list.keyword',
  867. 'order' => [
  868. '_count' => 'desc'
  869. ],
  870. 'size' => 20
  871. ]
  872. ],
  873. 'author_list' => [
  874. 'terms' => [
  875. 'field'=>'author_org_list.keyword',
  876. 'order' => [
  877. '_count' => 'desc'
  878. ],
  879. 'size' => 20
  880. ]
  881. ]
  882. ],
  883. 'highlight' => [
  884. 'pre_tags' => ["<font color='red'>"],
  885. 'post_tags' => ['</font>'],
  886. 'fields' => [
  887. 'title' => new \stdClass() ,
  888. 'author' => new \stdClass() ,
  889. 'keyword' => new \stdClass() ,
  890. 'abstract' => new \stdClass() ,
  891. 'album' => new \stdClass() ,
  892. ]
  893. ],
  894. "sort" => $this->setOrder($orderField , $order),
  895. ]
  896. ];
  897. return $params;
  898. }
  899. /**
  900. * 热点对应作者
  901. */
  902. public function refreshAuthors()
  903. {
  904. $value = Request::param('value') ?? '';
  905. if( ! $value) {
  906. return $this->_json_error('参数错误!');
  907. }
  908. $index = $this->currentLanguage();
  909. $params = [
  910. 'index' => $index,
  911. 'body' => [
  912. 'size' => 30,
  913. 'from' => 0,
  914. 'query' => [
  915. 'match' => [
  916. 'title' => $value
  917. ]
  918. ] ,
  919. ]
  920. ];
  921. $client = $this->getEsClient();
  922. $result = $client->search(
  923. $params
  924. );
  925. $data = $result['hits']['hits'];
  926. foreach ($data as $value) {
  927. $newArray[] = $value['_source'];
  928. }
  929. return $this->_json_succ(
  930. $this->authors($newArray)
  931. );
  932. }
  933. /**
  934. * 相关作者
  935. */
  936. protected function authors($data)
  937. {
  938. $authorOrg = array_column($data , 'author_org');
  939. $newArray = [];
  940. foreach ($authorOrg as $key => $value) {
  941. $newArray[$key]['name'] = $value[0]['author'] ?? '';
  942. $newArray[$key]['org'] = $value[0]['org'] ?? '';
  943. $newArray[$key]['value'] = $key+351;
  944. $newArray[$key]['symbolSize'] = $key+40;
  945. }
  946. return $this->uniqueArr($newArray , 'name');
  947. }
  948. /**
  949. * 文献搜索 相关作者
  950. */
  951. protected function relatedAuthors($data)
  952. {
  953. $newArray = [];
  954. foreach ($data['buckets'] as $key => $value){
  955. $authorOrg = explode('#',$value['key']);
  956. $newArray[$key]['name'] = Arr::get($authorOrg,0,'');
  957. $newArray[$key]['org'] = Arr::get($authorOrg,1,'');
  958. $newArray[$key]['value'] = $value['doc_count'] + 351;
  959. $newArray[$key]['symbolSize'] = $value['doc_count'];
  960. }
  961. return $this->uniqueArr($newArray , 'name');
  962. }
  963. /**
  964. * 二维数组某个键值唯一
  965. */
  966. protected function uniqueArr($arr , $key)
  967. {
  968. $newArray = [];
  969. foreach ($arr as $k => $v) {
  970. if(empty($newArray)) {
  971. $newArray[] = $arr[0][$key];
  972. } else {
  973. if(in_array($v[$key] , $newArray)) {
  974. unset($arr[$k]);
  975. } else {
  976. $newArray[] = $v[$key];
  977. }
  978. }
  979. }
  980. return array_slice($arr , 0 , 10 , false);
  981. }
  982. /**
  983. * 获取数组中的年份
  984. */
  985. protected function getYear($conditionArray)
  986. {
  987. foreach ($conditionArray as $key => $condition) {
  988. if('year' === $condition['select_field']) {
  989. return $conditionArray[$key]['field_value'];
  990. }
  991. }
  992. return '';
  993. }
  994. protected function getConditionArrayYear($conditionArray)
  995. {
  996. foreach ($conditionArray as $key => $condition) {
  997. if($condition['select_field'] === 'year') {
  998. return $condition['field_value'];
  999. }
  1000. }
  1001. return '';
  1002. }
  1003. /**
  1004. * 研究趋势
  1005. */
  1006. protected function researchTrends($year = '' , $conditionArray = '' , $index = '')
  1007. {
  1008. $years = $this->getConditionArrayYear($conditionArray);
  1009. $query = [];
  1010. if ($years){
  1011. $year = $years;
  1012. $yearArr = explode(',' , $year);
  1013. foreach ($conditionArray as $key => $condition) {
  1014. if($condition['select_field'] === 'year') {
  1015. unset($conditionArray[$key]);
  1016. }
  1017. }
  1018. $query['bool']['must'][] = [
  1019. 'range' => [
  1020. 'year' => [
  1021. 'gte' => $yearArr[0] ,
  1022. 'lte' => $yearArr[1]
  1023. ]
  1024. ]
  1025. ];
  1026. }
  1027. foreach ($conditionArray as $value) {
  1028. $query['bool']['should'][] = [
  1029. 'match_phrase' => [
  1030. $value['select_field'] => $value['field_value']
  1031. ]
  1032. ];
  1033. }
  1034. $query['bool']['minimum_should_match'] = 1;
  1035. $params = [
  1036. 'index' => $index,
  1037. 'body' => [
  1038. 'size' => 1 ,
  1039. 'query' => $query ,
  1040. 'aggs' => [
  1041. 'docStat' => [
  1042. 'terms' => [
  1043. 'field' => 'year' ,
  1044. 'order' => [
  1045. '_key' => 'asc'
  1046. ] ,
  1047. 'size' => 200
  1048. ] ,
  1049. 'aggs' => [
  1050. 'citedPerYear' => [
  1051. 'sum' => [
  1052. 'field' => 'citation_relate_count'
  1053. ]
  1054. ]
  1055. ]
  1056. ],
  1057. ],
  1058. 'sort' => [
  1059. [
  1060. 'year' => [
  1061. 'order' => 'desc'
  1062. ]
  1063. ]
  1064. ]
  1065. ]
  1066. ];
  1067. $client = $this->getEsClient();
  1068. $result = $client->search($params);
  1069. return $result['aggregations']['docStat']['buckets'] ?? [];
  1070. }
  1071. /**
  1072. * 关联研究
  1073. */
  1074. protected function associationStudy($data)
  1075. {
  1076. $keywordArr = array_column($data['buckets'] , 'key');
  1077. /**
  1078. * 热点词以及热点值
  1079. */
  1080. $newArray = [];
  1081. foreach ($keywordArr as $kkk => $vvv) {
  1082. $newArray[$kkk]['name'] = $vvv;
  1083. $newArray[$kkk]['value'] = random_int(5000 , 10000);
  1084. }
  1085. return [
  1086. 'search' => '',
  1087. 'keyword' => $newArray
  1088. ];
  1089. }
  1090. /**
  1091. * 搜索关键词
  1092. */
  1093. protected function searchKeyword($keyword):array
  1094. {
  1095. if( ! $keyword) {
  1096. return [
  1097. 'keyword' => '' ,
  1098. 'keyword_desc' => ''
  1099. ];
  1100. }
  1101. $keywordDesc = XyZskDisease::where("name" , "like" , "%$keyword")->whereOr('alias' , 'like' , "%$keyword%")->value('sickOverview') ?? '';
  1102. return [
  1103. 'keyword' => $keyword ,
  1104. 'keyword_desc' => $keywordDesc
  1105. ];
  1106. }
  1107. /**
  1108. * 搜索历史
  1109. */
  1110. public function history()
  1111. {
  1112. $uid = Request::param('uid') ?? '833456167';
  1113. if( ! $uid) {
  1114. $uid = 833456167;
  1115. //return $this->_json_error('参数有误!');
  1116. }
  1117. $page = Request::param('page') ?? 1;
  1118. $limit = ($page - 1) * $this->pagesize;
  1119. $list = History::where('uid' , $uid)
  1120. ->order('id' , 'desc')
  1121. ->limit($limit , $this->pagesize)
  1122. ->select()
  1123. ->toArray();
  1124. if(empty($list)) {
  1125. return $this->_json_succ(
  1126. []
  1127. );
  1128. }
  1129. return $this->_json_succ(
  1130. $list
  1131. );
  1132. }
  1133. /**
  1134. * 字段描述
  1135. */
  1136. protected function getFieldDesc($field , $tag)
  1137. {
  1138. if('select_field' === $tag) {
  1139. $fieldDesc = [
  1140. 'title' => '标题' ,
  1141. 'author' => '作者' ,
  1142. 'abstract' => '摘要' ,
  1143. 'keyword' => '关键词',
  1144. 'funds' => '基金' ,
  1145. 'references' => '参考文献' ,
  1146. 'doi' => 'doi' ,
  1147. 'album' => '期刊' ,
  1148. 'organization'=> '作者单位' ,
  1149. 'title_' => '篇名' ,
  1150. 'author_' => '第一作者' ,
  1151. 'author_o' => '通讯作者' ,
  1152. 'number' => '分类号' ,
  1153. 'references_' => '文献来源' ,
  1154. 'year' => '发表时间'
  1155. ];
  1156. }
  1157. if('select_type' === $tag) {
  1158. $fieldDesc = [
  1159. 'term' => '精准' ,
  1160. 'match' => '模糊'
  1161. ];
  1162. }
  1163. if('select_condition' === $tag) {
  1164. $fieldDesc = [
  1165. 'and' => 'And' ,
  1166. 'or' => 'Or'
  1167. ];
  1168. }
  1169. return $fieldDesc[$field] ?? '';
  1170. }
  1171. /**
  1172. * 设置排序
  1173. */
  1174. protected function setOrder($order_field = 'id' , $order = 'asc')
  1175. {
  1176. return [
  1177. $order_field => array(
  1178. 'order' => $order
  1179. )
  1180. ];
  1181. }
  1182. /**
  1183. * 测试
  1184. */
  1185. public function setOrderOther($orderArray = [])
  1186. {
  1187. if(empty($orderArray)) {
  1188. return [
  1189. [
  1190. 'id' => [
  1191. 'order' => 'asc'
  1192. ]
  1193. ]
  1194. ];
  1195. }
  1196. $newOrder = [];
  1197. foreach($orderArray as $key => $orders) {
  1198. $newOrder[$key] = [
  1199. $orders['order_field'] => [
  1200. 'order' => $orders['order']
  1201. ]
  1202. ];
  1203. }
  1204. return $newOrder;
  1205. }
  1206. /**
  1207. * 设置 fieldData
  1208. */
  1209. public function setFieldData()
  1210. {
  1211. $index = $this->currentLanguage();
  1212. $type = Request::param('type');
  1213. $field = Request::param('field');
  1214. if( ! $index || ! $field || ! $type) {
  1215. return $this->_json_error('请求错误!');
  1216. }
  1217. $url = "http://121.36.74.125:9200/".$index.'/'.$type.'/_mapping';
  1218. return $this->_json_succ(
  1219. $this->curl($url , $field)
  1220. );
  1221. }
  1222. /**
  1223. * Curl
  1224. */
  1225. protected function curl($url , $field)
  1226. {
  1227. $curl = curl_init(); // 初始化
  1228. curl_setopt($curl, CURLOPT_URL, $url); // 设置抓取的url
  1229. $data = [
  1230. 'properties' => [
  1231. $field => [
  1232. 'type' => 'numeric' , // text
  1233. 'fielddata' => true
  1234. ]
  1235. ]
  1236. ];
  1237. $jsonData = json_encode($data);
  1238. curl_setopt($curl, CURLOPT_HTTPHEADER, array(
  1239. 'Content-Type: application/json'
  1240. )
  1241. );
  1242. curl_setopt($curl, CURLOPT_POST, 1); // 设置post方式提交
  1243. curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonData); // post提交的数据
  1244. curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 设置获取的信息以文件流的形式返回,而不是直接输出。
  1245. $output = curl_exec($curl);
  1246. curl_close($curl);
  1247. $result = json_decode($output, true);
  1248. return $result;
  1249. }
  1250. /**
  1251. * 收藏
  1252. */
  1253. public function docCollection()
  1254. {
  1255. $uid = Request::param('uid') ?? '833456167';
  1256. $md5 = Request::param('md5') ?? '';
  1257. $tag = Request::param('tag') ?? '';
  1258. $title = Request::param('title') ?? '';
  1259. $pmid = Request::param('PMID') ?? '';
  1260. if(empty($uid)){
  1261. $uid = 833456167;
  1262. }
  1263. if(! $uid || ! $tag || ! $title) {
  1264. return $this->_json_error('参数请求有误!');
  1265. }
  1266. $value = '';
  1267. if ( $md5&& !$pmid){
  1268. $value = $md5;
  1269. }
  1270. if ( !$md5&& $pmid){
  1271. $md5 = $pmid;
  1272. $value = $pmid;
  1273. }
  1274. $where = [
  1275. 'uid' => $uid ,
  1276. 'md5' => $value ,
  1277. ];
  1278. if('collection' === $tag) {
  1279. $check = EsCollection::where($where)->find();
  1280. if($check) {
  1281. if(2 == $check->status) {
  1282. EsCollection::where($where)->update(
  1283. [
  1284. 'status' => 1,
  1285. 'title' => $title
  1286. ]
  1287. );
  1288. }
  1289. } else {
  1290. EsCollection::create(
  1291. [
  1292. 'uid' => $uid ,
  1293. 'md5' => $md5 ,
  1294. 'title' => $title
  1295. ]
  1296. );
  1297. }
  1298. }
  1299. if('cancelCollection' === $tag) {
  1300. EsCollection::where($where)->update(
  1301. [
  1302. 'status' => 2
  1303. ]
  1304. );
  1305. }
  1306. return $this->_json_succ();
  1307. }
  1308. /**
  1309. * 我的收藏列表
  1310. */
  1311. public function myCollectionList()
  1312. {
  1313. $params = input('post.');
  1314. $uid = $params['uid'] ?? '833456167';
  1315. /**
  1316. * 搜索参数
  1317. */
  1318. $search = $params['search'] ?? '';
  1319. $tag = $params['tag'] ?? '';
  1320. $where = [];
  1321. /**
  1322. * 文献标题搜索
  1323. */
  1324. if( $search ) {
  1325. $where[] = ['title' , 'like' , "%$search%"];
  1326. }
  1327. /**
  1328. * 文献标签搜索
  1329. */
  1330. if( $tag ) {
  1331. $where[] = ['tags' , 'like' , "%$tag%"];
  1332. }
  1333. $page = $params['page'] ?? 1;
  1334. $limit = ($page - 1) * $this->pagesize;
  1335. $myEsCollectionList = EsCollection::where($where)->where([
  1336. 'uid' => $uid ,
  1337. 'status' => 1
  1338. ])->limit($limit , $this->pagesize)->select()->toArray();
  1339. if( ! $myEsCollectionList ) {
  1340. return $this->_json_error('暂无收藏数据!');
  1341. }
  1342. /**
  1343. * 获取收藏文献数据(es)
  1344. */
  1345. $client = $this->getEsClient();
  1346. $uniqIdArr = array_column($myEsCollectionList , 'md5');
  1347. foreach($uniqIdArr as $uniqId) {
  1348. $params = [
  1349. 'index' => $this->index,
  1350. 'body' => [
  1351. 'query' => [
  1352. 'bool' => [
  1353. 'should' => [
  1354. [
  1355. "constant_score" => [
  1356. "filter" => [
  1357. "match" => [
  1358. 'uniq_id' => $uniqId
  1359. ]
  1360. ]
  1361. ]
  1362. ],
  1363. [
  1364. "constant_score" => [
  1365. "filter" => [
  1366. "match" => [
  1367. 'PMID' => $uniqId
  1368. ]
  1369. ]
  1370. ]
  1371. ]
  1372. ]
  1373. ]
  1374. ],
  1375. ]
  1376. ];
  1377. /**
  1378. * 结果集
  1379. */
  1380. $result[] = $client->search($params);
  1381. }
  1382. /**
  1383. * 获取source集合
  1384. */
  1385. foreach ($result as $k => $v) {
  1386. $hits[] = $result[$k]['hits']['hits'][0] ?? [];
  1387. }
  1388. if( ! $hits) {
  1389. $sourceArr = [];
  1390. } else {
  1391. /**
  1392. * 将mysql收藏文献标签(tags)追加到es数据
  1393. */
  1394. $sourceArr = array_column($hits , '_source');
  1395. foreach ($sourceArr as $kk => $vv) {
  1396. foreach ($myEsCollectionList as $vvv) {
  1397. if($vv['uniq_id'] === $vvv['md5']) {
  1398. $sourceArr[$kk]['tags'] = $vvv['tags'];
  1399. }
  1400. }
  1401. $sourceArr[$kk]['is_collection'] = $this->checkIsCollectionDoc($uid , $vv['uniq_id']);
  1402. $sourceArr[$kk]['click_count'] = ClickCount::where('md5' , $vv['uniq_id'])->value('click_count') ?? 0;
  1403. }
  1404. }
  1405. /**
  1406. * 收藏文献标签集合
  1407. */
  1408. $newTagList = [];
  1409. foreach ($myEsCollectionList as $tkey => $tval) {
  1410. $newTagList[] = explode(',' , $tval['tags']);
  1411. }
  1412. $newTagList = array_filter($this->mergeArray($newTagList));
  1413. return $this->_json_succ(
  1414. [
  1415. 'tags_list' => $newTagList ,
  1416. 'list' => $sourceArr
  1417. ]
  1418. );
  1419. }
  1420. /**
  1421. * 合并二维数组下的多个一维数组
  1422. */
  1423. protected function mergeArray($arr)
  1424. {
  1425. return call_user_func_array('array_merge' , $arr);
  1426. }
  1427. /**
  1428. * 添加收藏标签
  1429. * @return
  1430. */
  1431. public function docCollectionTags()
  1432. {
  1433. $uid = Request::param('uid') ?? '833456167';
  1434. $md5 = Request::param('md5') ?? '';
  1435. $tags = Request::param('tags') ?? [];
  1436. if( ! $uid || ! $md5 || empty($tags)) {
  1437. return $this->_json_error('参数请求有误!');
  1438. }
  1439. $collection = EsCollection::where([
  1440. 'uid' => $uid ,
  1441. 'md5' => $md5 ,
  1442. 'status' => 1 ,
  1443. ])->find();
  1444. if ( ! $collection ) {
  1445. return $this->_json_error('文献不存在');
  1446. }
  1447. $collection->tags = implode(',' , $tags);
  1448. $collection->save();
  1449. return $this->_json_succ();
  1450. }
  1451. /**
  1452. * 列表返回统一封装
  1453. */
  1454. protected function dataAssemble($uid , $total , $data , $otherOrderField = '' , $otherOrder = ''):array
  1455. {
  1456. if(empty($data)) {
  1457. return [];
  1458. }
  1459. // foreach($data as $key => $value) {
  1460. // if(stripos($value['abstract'] , '<正>') !== false) {
  1461. // $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']);
  1462. // }
  1463. // /**
  1464. // * 文献点击量 是否收藏
  1465. // */
  1466. // $data[$key]['is_collection'] = $this->checkIsCollectionDoc($uid , $value['uniq_id']);
  1467. // $data[$key]['click_count'] = ClickCount::where('md5' , $value['uniq_id'])->value('click_count') ?? 0;
  1468. // }
  1469. $md5Arr = [];
  1470. /**
  1471. * 处理文献中带 <正>
  1472. */
  1473. foreach($data as $key => $value)
  1474. {
  1475. if(isset($value['abstract'])) {
  1476. $data[$key]['abstract'] = str_replace('<正>' , ' ' , $value['abstract']);
  1477. }
  1478. if(isset($value['periodical_md5'])) {
  1479. $md5Arr[] = $value['periodical_md5'];
  1480. }
  1481. }
  1482. //文献 收藏 点击量
  1483. $md5Res = EsCollection::where(['uid' => $uid])->whereIn('md5', $md5Arr)->select()->toArray();
  1484. $clickCountRes = ClickCount::whereIn('md5', $md5Arr)->select()->toArray();
  1485. foreach ($data as $key => $value) {
  1486. $data[$key]['is_collection'] = 2;
  1487. $data[$key]['click_count'] = 0;
  1488. if (isset($value['periodical_md5'])) {
  1489. if ($collectionKey = array_search($value['periodical_md5'], array_column($md5Res, 'md5'))) {
  1490. if ($md5Res[$collectionKey]['status'] != 2) {
  1491. $data[$key]['is_collection'] = 1;
  1492. }
  1493. }
  1494. if ($clickCountKey = array_search($value['periodical_md5'], array_column($clickCountRes, 'md5'))) {
  1495. $data[$key]['click_count'] = $clickCountRes[$clickCountKey]['click_count'];
  1496. }
  1497. }
  1498. }
  1499. /**
  1500. * 点击量动态数组排序
  1501. */
  1502. if('click_count' === $otherOrderField) {
  1503. $click_count = array_column($data , 'click_count');
  1504. $otherOrder = 'asc' === $otherOrder ? SORT_ASC : SORT_DESC;
  1505. array_multisort($click_count , $otherOrder , $data);
  1506. }
  1507. return [
  1508. 'total' => $total,
  1509. 'total_page' => ceil($total / $this->pagesize),
  1510. 'data' => $data
  1511. ];
  1512. }
  1513. /**
  1514. * 用户是否收藏文献
  1515. * 1.已收藏 2.未收藏
  1516. */
  1517. protected function checkIsCollectionDoc($uid , $uniq_id)
  1518. {
  1519. $check = EsCollection::where(['uid' => $uid , 'md5' => $uniq_id])->find();
  1520. if( ! $check || 2 == $check->status) {
  1521. return 2;
  1522. }
  1523. return 1;
  1524. }
  1525. /**
  1526. * 换一批
  1527. */
  1528. public function randomDoc()
  1529. {
  1530. $tag = Request::param('tag') ?? $this->index;
  1531. $uid = Request::param('uid') ?? '833456167';
  1532. $index = $tag;
  1533. $field = Request::param('field') ?? 'title , periodical_md5';
  1534. $page = Request::param('page') ?? 1;
  1535. $limit = ($page - 1) * 10;
  1536. //$index = $this->currentLanguage();
  1537. $index = 'document_zh';
  1538. $params = [
  1539. 'index' => $index,
  1540. 'body' => [
  1541. 'from' => $limit,
  1542. 'size' => 10,
  1543. 'query' => [
  1544. 'match_all' => (object)[] , // 查询全部
  1545. ],
  1546. "_source" => ['title' , 'periodical_md5' , 'uniq_id'], // 获取制定字段
  1547. //"sort" => $this->setOrder('year' , 'desc'),
  1548. ],
  1549. ];
  1550. $result = $this->esCommonGetData($params);
  1551. return $this->_json_succ($result);
  1552. }
  1553. /**
  1554. * 相关推荐
  1555. *
  1556. * @param $tag string 模块标识 (学科分析 | 学者分析 | 期刊分析)
  1557. * @param $value string 分析值
  1558. * @param $type string 类型 (最新 | 最高)
  1559. * @return Json
  1560. */
  1561. public function relationRecommend()
  1562. {
  1563. $org = Request::param('org') ?? '';
  1564. $tag = Request::param('tag') ?? '';
  1565. $value = Request::param('value') ?? '';
  1566. $type = Request::param('type') ?? 'highest';
  1567. if( ! $tag || ! $value || ! $type) {
  1568. return $this->_json_error('请求参数有误!');
  1569. }
  1570. $page = Request::param('page') ?? 1;
  1571. $limit = ($page - 1) * $this->pagesize;
  1572. if('department' === $tag) {
  1573. $selectField = 'title';
  1574. $selectType = 'match_phrase';
  1575. }
  1576. if('album' === $tag) {
  1577. $selectField = 'album.keyword';
  1578. $selectType = 'match';
  1579. }
  1580. if('highest' === $type) {
  1581. $orderField = 'citation_relate_count';
  1582. $order = 'desc';
  1583. }
  1584. if('newest' === $type) {
  1585. $orderField = 'year';
  1586. $order = 'desc';
  1587. }
  1588. if('author' === $tag) {
  1589. $query = [
  1590. 'bool' => [
  1591. 'must' => [
  1592. [
  1593. 'nested' => [
  1594. 'path' => 'author_org',
  1595. 'query' => [
  1596. 'bool' => [
  1597. 'must' => [
  1598. [
  1599. 'match_phrase' => [
  1600. 'author_org.author' => $value
  1601. ]
  1602. ],
  1603. [
  1604. 'match_phrase' => [
  1605. 'author_org.org' => $org
  1606. ]
  1607. ]
  1608. ]
  1609. ]
  1610. ]
  1611. ]
  1612. ],
  1613. [
  1614. 'match_phrase' => [
  1615. 'author' => $value
  1616. ]
  1617. ],
  1618. [
  1619. 'range' => [
  1620. 'year' => [
  1621. 'gte' => 2002 ,
  1622. 'lte' => 2040
  1623. ]
  1624. ]
  1625. ]
  1626. ]
  1627. ]
  1628. ];
  1629. }else{
  1630. $query = [
  1631. 'bool' => [
  1632. 'must' => [
  1633. [
  1634. $selectType => [
  1635. $selectField => $value
  1636. ]
  1637. ],
  1638. [
  1639. 'range' => [
  1640. 'year' => [
  1641. 'gte' => 2002 ,
  1642. 'lte' => 2040
  1643. ]
  1644. ]
  1645. ]
  1646. ]
  1647. ]
  1648. ];
  1649. }
  1650. $index = $this->currentLanguage();
  1651. //$source = ["author" , "title" , "year" , "citation_relate_count" , "album" , "periodical_md5" , "author_list"];
  1652. $params = [
  1653. 'index' => $index ,
  1654. 'from' => $limit ,
  1655. 'size' => $this->pagesize,
  1656. 'body' => [
  1657. 'query' => $query,
  1658. 'highlight' => [
  1659. 'pre_tags' => ["<font color='red'>"],
  1660. 'post_tags' => ['</font>'],
  1661. 'fields' => [
  1662. 'author' => new \stdClass() ,
  1663. ]
  1664. ],
  1665. 'sort' => $this->setOrder($orderField , $order)
  1666. ]
  1667. ];
  1668. $client = $this->getEsClient();
  1669. $esData = $client->search(
  1670. $params
  1671. );
  1672. $result = $esData['hits']['hits'];
  1673. $data = $result;
  1674. /**
  1675. * 关键词高亮
  1676. */
  1677. foreach($data as $key => $value) {
  1678. if(isset($value['highlight']['author']) ) {
  1679. $authorList = explode(";" , $value['highlight']['author'][0]);
  1680. } else {
  1681. $authorList = $data[$key]['_source']['author_list'];
  1682. }
  1683. $data[$key]['_source']['author_list'] = $authorList;
  1684. }
  1685. return $this->_json_succ(
  1686. [
  1687. 'total' => $esData['hits']['total'],
  1688. 'total_page' => ceil($esData['hits']['total'] / $this->pagesize) ,
  1689. 'list' => array_column($data , '_source')
  1690. ]
  1691. );
  1692. }
  1693. /**
  1694. * 清除
  1695. */
  1696. public function clear()
  1697. {
  1698. $uid = Request::param('uid') ?? '833456167';
  1699. $id = Request::param('id') ?? '';
  1700. $tag = Request::param('tag') ?? '';
  1701. if(! $uid || ! $tag) {
  1702. return $this->_json_error('请求有误!');
  1703. }
  1704. if('clear' === $tag) {
  1705. History::where('uid' , $uid)->delete();
  1706. } else {
  1707. if($id) {
  1708. History::where('id' , $id)->delete();
  1709. }
  1710. }
  1711. return $this->_json_succ();
  1712. }
  1713. }