EsAuthor.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. <?php
  2. namespace app\controller;
  3. use think\facade\Request;
  4. use think\helper\Arr;
  5. /**
  6. * 学者分析
  7. */
  8. class EsAuthor extends CommonEsController
  9. {
  10. protected $pageSize = 20;
  11. public function test()
  12. {
  13. return $this->_json_succ(
  14. [
  15. 'name' => 'knowledge',
  16. 'value' => 'sk'
  17. ]
  18. );
  19. }
  20. /**
  21. * 首页
  22. */
  23. public function index()
  24. {
  25. $field = Request::param('field') ?? 'author_org_list';
  26. $page = Request::param('page') ?? 1;
  27. $limit = ($page - 1) * $this->pageSize;
  28. $params = [
  29. 'index' => 'document_zh',
  30. // 'index' => 'document_zh,document_en',
  31. 'body' => [
  32. 'from' => $limit,
  33. 'size' => $this->pagesize,
  34. 'query' => [
  35. 'match_all' => (object)[], // 查询全部
  36. ],
  37. "_source" => $field, // 获取制定字段
  38. //"sort" => $this->setOrderOther(),
  39. ]
  40. ];
  41. //print_r($params);die;
  42. $result = $this->esCommonGetData($params);
  43. $data = $result['data'];
  44. $column = array_column($data, 'author_org_list');
  45. $author = array_merge(
  46. //$column[0] ?? [], $column[1] ?? [],$column[2] ?? [],$column[3] ??[],$column[4] ?? [] , $column[5] ?? []
  47. $column[0] ?? [], $column[1] ?? [], $column[2] ?? []
  48. );
  49. if(count($author) < 12){
  50. $author = array_merge($author,$column[3] ?? [],$column[4] ?? [],$column[5] ?? []);
  51. }
  52. /**
  53. * 查询作者的成果数和被引频次
  54. */
  55. $newAuthorOrg = [];
  56. foreach ($author as $key => $value) {
  57. $authorOrg = explode('#', $value);
  58. $newAuthorOrg[$key]['author'] = $authorOrg[0];
  59. $newAuthorOrg[$key]['org'] = $authorOrg[1];
  60. $bucket = $this->getAuthorCount($value);
  61. $newAuthorOrg[$key]['achievement_num'] = $bucket[0]['doc_count'] ?? '';
  62. $newAuthorOrg[$key]['citation_frequency'] = $bucket[0]['citedCnt']['value'] ?? '';
  63. }
  64. return $this->_json_succ(
  65. $newAuthorOrg
  66. );
  67. }
  68. /**
  69. * 获取作者的机构
  70. */
  71. protected function getAuthorOrg($author, $authorList)
  72. {
  73. // foreach ($authorList as $value){
  74. // $arr = explode('#',$value);
  75. // if (in_array($author,$arr)){
  76. // return Arr::get($arr,1);
  77. // }
  78. // }
  79. $params = [
  80. 'index' => 'document_zh',
  81. 'from' => 0,
  82. 'size' => 1,
  83. 'body' => [
  84. 'query' => [
  85. 'match_phrase' => [
  86. 'author_org_list' => $author
  87. ]
  88. ]
  89. ]
  90. ];
  91. $client = $this->getEsClient();
  92. $result = $client->search($params);
  93. if (!isset($result['hits']['hits'][0])) {
  94. return '';
  95. }
  96. $org = $result['hits']['hits'][0]['_source']['author_org'];
  97. foreach ($org as $value) {
  98. if (($author == $value['author']) || (stripos($value['author'], $author) !== false)) {
  99. return $value['org'];
  100. }
  101. }
  102. return '';
  103. }
  104. /**
  105. * 作者的成果数 | 被引频次
  106. */
  107. protected function getAuthorCount($authors)
  108. {
  109. $query['bool']['should'][] = [
  110. 'term' => [
  111. 'author_org_list.keyword' => [
  112. 'value' => $authors
  113. ]
  114. ]
  115. ];
  116. $size = 1;
  117. $params = [
  118. 'index' => 'document_zh',
  119. 'body' => [
  120. 'size' => 1,
  121. 'query' => $query,
  122. 'aggs' => [
  123. 'author' => [
  124. 'terms' => [
  125. 'field' => 'author_list.keyword',
  126. 'size' => $size,
  127. 'order' => [
  128. '_count' => 'desc'
  129. ]
  130. ],
  131. 'aggs' => [
  132. 'citedCnt' => [
  133. 'sum' => [
  134. 'field' => 'citation_relate_count'
  135. ]
  136. ]
  137. ]
  138. ]
  139. ]
  140. ]
  141. ];
  142. $client = $this->getEsClient();
  143. $result = $client->search(
  144. $params
  145. );
  146. return $result['aggregations']['author']['buckets'];
  147. }
  148. /**
  149. * 作者对应的所有机构(下拉)
  150. */
  151. public function getSelectOrgs()
  152. {
  153. $author = Request::param('author') ?? '';
  154. if (!$author) {
  155. return $this->_json_error('请求参数错误!');
  156. }
  157. $page = Request::param('page') ?? 1;
  158. $size = 100;
  159. $limit = ($page - 1) * $size;
  160. $params = [
  161. 'index' => 'document_zh',
  162. 'from' => $limit,
  163. 'size' => $size,
  164. 'body' => [
  165. 'query' => [
  166. 'match_phrase' => [
  167. 'author_org_list' => $author
  168. ]
  169. ]
  170. ]
  171. ];
  172. $client = $this->getEsClient();
  173. $result = $client->search($params);
  174. $total = $result['hits']['total'];
  175. if (0 == $total) {
  176. return $this->_json_error('未查到相关信息!');
  177. }
  178. $hits = $result['hits']['hits'];
  179. $source = array_column($hits, '_source');
  180. $authorOrgList = array_column($source, 'author_org_list');
  181. $authorSelectList = [];
  182. foreach ($authorOrgList as $value) {
  183. if (!is_array($value)) {
  184. $varr = explode('#', $value);
  185. if ($author == $varr[0]) {
  186. $authorSelectList[] = $value;
  187. }
  188. } else {
  189. foreach ($value as $v) {
  190. $varr = explode('#', $v);
  191. if ($author == $varr[0]) {
  192. $authorSelectList[] = $v;
  193. }
  194. }
  195. }
  196. }
  197. if (empty($authorSelectList)) {
  198. return $this->_json_succ(
  199. []
  200. );
  201. }
  202. foreach ($authorSelectList as $kk => $vv) {
  203. $arr = explode('#', $vv);
  204. $newArray[$kk]['author'] = $arr[0];
  205. $newArray[$kk]['org'] = $arr[1];
  206. }
  207. $orgs = array_values(array_unique(array_column($newArray, 'org')));
  208. return $this->_json_succ(
  209. [
  210. 'orgs' => $orgs
  211. ]
  212. );
  213. }
  214. /**
  215. * 搜索
  216. */
  217. public function search()
  218. {
  219. $author = Request::param('author') ?? '';
  220. $org = Request::param('org') ?? '';
  221. $tag = Request::param('tag') ?? '';
  222. $page = Request::param('page') ?? 1;
  223. $pageSize = Request::param('pageSize') ?? 12;
  224. if (!$author && !$org) {
  225. return $this->_json_error('请求参数有误!');
  226. }
  227. if ($author && $org) {
  228. $value = $author . '#' . $org;
  229. $selectTag = 'author-org';
  230. $size = 1;
  231. }
  232. if ($author && !$org) {
  233. $value = $author;
  234. $selectTag = 'author';
  235. $size = 1000;
  236. }
  237. if (!$author && $org) {
  238. $value = $org;
  239. $selectTag = 'org';
  240. $size = 1000;
  241. }
  242. $field = 'author_org_list';
  243. $params = [
  244. 'index' => 'document_zh',
  245. 'size' => 1,
  246. 'body' => [
  247. 'query' => [
  248. 'match_phrase' => [
  249. $field => $value
  250. ]
  251. ],
  252. 'aggs' => [
  253. 'author_group' => [
  254. 'terms' => [
  255. 'field' => 'author_org_list.keyword',
  256. 'size' => $size,
  257. ]
  258. ]
  259. ]
  260. ]
  261. ];
  262. $client = $this->getEsClient();
  263. $result = $client->search(
  264. $params
  265. );
  266. $total = $result['hits']['total'];
  267. if (0 == $total) {
  268. return $this->_json_error('未查到相关信息!');
  269. }
  270. $newArray = [];
  271. $authorOrgGroup = $result['aggregations']['author_group']['buckets'];
  272. foreach ($authorOrgGroup as $kk => $vv) {
  273. $arr = explode('#', $vv['key']);
  274. $newArray[$kk]['author'] = $arr[0];
  275. $newArray[$kk]['org'] = $arr[1];
  276. }
  277. if ($selectTag == 'org'){
  278. $uniqueArray = $this->uniqueArr($newArray, 'author', $org);
  279. }else{
  280. $uniqueArray = $this->uniqueArr($newArray, 'org', $author);
  281. }
  282. $newArray = [];
  283. foreach ($uniqueArray as $key => $value) {
  284. //实现分页操作
  285. if ((($page - 1) * $pageSize) > $key) {
  286. continue;
  287. }
  288. if (($page * $pageSize - 1) < $key) {
  289. continue;
  290. }
  291. $newArray[$key]['author'] = $value['author'];
  292. $newArray[$key]['org'] = $value['org'];
  293. $bucket = $this->getAuthorCount($value['author'] . '#' . $value['org']);
  294. $newArray[$key]['achievement_num'] = $bucket[0]['doc_count'] ?? 0;
  295. $newArray[$key]['citation_frequency'] = $bucket[0]['citedCnt']['value'] ?? 0;
  296. }
  297. return $this->_json_succ(
  298. [
  299. 'total' => count($uniqueArray),
  300. 'total_page' => ceil(count($uniqueArray) / $pageSize),
  301. 'data' => $newArray,
  302. ]
  303. );
  304. }
  305. /**
  306. * 二维数组某个键值唯一
  307. */
  308. protected function uniqueArr($arr, $key, $value)
  309. {
  310. $newArray = [];
  311. foreach ($arr as $k => $v) {
  312. if (empty($newArray)) {
  313. $newArray[] = $arr[0][$key];
  314. } else {
  315. if (in_array($v[$key], $newArray)) {
  316. unset($arr[$k]);
  317. } else {
  318. $newArray[] = $v[$key];
  319. }
  320. }
  321. }
  322. if ('org' === $key) {
  323. $authorOrgList = [];
  324. foreach ($newArray as $kk => $vv) {
  325. $authorOrgList[$kk]['author'] = $value;
  326. $authorOrgList[$kk]['org'] = $vv;
  327. }
  328. return $authorOrgList;
  329. }
  330. if ('author' === $key) {
  331. $orgAuthorList = [];
  332. foreach ($newArray as $kkk => $vvv) {
  333. $orgAuthorList[$kkk]['author'] = $vvv;
  334. $orgAuthorList[$kkk]['org'] = $value;
  335. }
  336. return array_slice($orgAuthorList, 0, 20);
  337. }
  338. return [];
  339. }
  340. /**
  341. * 获取学者机构
  342. */
  343. public function getOrganization()
  344. {
  345. $author = Request::param('author') ?? '';
  346. $title = strip_tags(Request::param('title')) ?? '';
  347. $params = [
  348. 'index' => 'document_zh',
  349. 'body' => [
  350. 'size' => 1,
  351. 'query' => [
  352. 'bool' => [
  353. 'must' => [
  354. [
  355. 'term' => [
  356. 'title.keyword' => $title,
  357. ]
  358. ],
  359. [
  360. 'term' => [
  361. 'author_list.keyword' => $author
  362. ]
  363. ]
  364. ],
  365. ]
  366. ],
  367. //"_source" => $field, // 获取制定字段
  368. //"sort" => $this->setOrderOther(),
  369. ]
  370. ];
  371. $client = $this->getEsClient();
  372. $result = $client->search($params);
  373. $total = $result['hits']['total'];
  374. $data = $result['hits']['hits'];
  375. $org['org'] = '';
  376. if (0 == $total) {
  377. return $this->_json_succ(
  378. $org
  379. );
  380. }
  381. $source = array_column($data, '_source');
  382. $authorOrgList = array_column($source, 'author_org_list');
  383. $str = [];
  384. foreach ($authorOrgList as $key => $value) {
  385. $valueCount = count($authorOrgList[$key]);
  386. for ($i = 0; $i < $valueCount; $i++) {
  387. $orgAuthor = $value[$i];
  388. if (stripos($orgAuthor, $author) !== false) {
  389. $str = $orgAuthor;
  390. }
  391. }
  392. }
  393. if (empty($str)) {
  394. return $this->_json_succ(
  395. $org
  396. );
  397. }
  398. $authorOrgArr = explode('#', $str);
  399. $org = $authorOrgArr[1] ?? '';
  400. return $this->_json_succ(
  401. [
  402. 'org' => $org
  403. ]
  404. );
  405. }
  406. /**
  407. * 学者详情
  408. */
  409. public function getAuthorDetailByName()
  410. {
  411. $author = Request::param('author') ?? '';
  412. $org = Request::param('org') ?? '';
  413. if (!$author || !$org) {
  414. return $this->_json_error('请求参数有误!');
  415. }
  416. $authorDetail = [
  417. 'author' => $author,
  418. 'org' => $org,
  419. 'achievement_num' => $this->authorDetail($author, $org, 'achievement_num'),
  420. 'citation_frequency' => $this->authorDetail($author, $org, 'citation_frequency'),
  421. 'cooperation_partner_num' => $this->authorDetail($author, $org, 'cooperation_partner_num'),
  422. 'cooperation_organization_num' => $this->authorDetail($author, $org, 'cooperation_organization_num'),
  423. 'co_author_list' => $this->authorDetail($author, $org, 'co_author_list'),
  424. 'post_trend' => $this->authorDetail($author, $org, 'post_trend'),
  425. 'cited_trend' => $this->authorDetail($author, $org, 'cited_trend'),
  426. 'research_topic' => $this->authorDetail($author, $org, 'research_topic'),
  427. 'co_organization_list' => $this->authorDetail($author, $org, 'co_organization_list'),
  428. 'domain' => $this->authorDetail($author, $org, 'domain')
  429. ];
  430. return $this->_json_succ(
  431. $authorDetail
  432. );
  433. }
  434. /**
  435. * 学者详情统计
  436. */
  437. protected function authorDetail($author, $org, $tag)
  438. {
  439. //$index = $this->currentLanguage();
  440. $index = 'document_zh';
  441. $params = [
  442. 'index' => $index,
  443. 'body' => [
  444. 'query' => [
  445. 'bool' => [
  446. 'should' => [
  447. 'term' => [
  448. 'author_org_list.keyword' => [
  449. 'value' => $author . '#' . $org
  450. ]
  451. ]
  452. ],
  453. 'minimum_should_match' => 1
  454. ]
  455. ],
  456. 'aggs' => [
  457. 'corAuthorCnt' => [
  458. 'cardinality' => [
  459. 'field' => 'author_list.keyword',
  460. 'precision_threshold' => 1000
  461. ]
  462. ],
  463. 'corOrgCnt' => [
  464. 'cardinality' => [
  465. 'field' => 'organization_parsed.keyword'
  466. ]
  467. ],
  468. 'citedCnt' => [
  469. 'sum' => [
  470. 'field' => 'citation_relate_count'
  471. ]
  472. ],
  473. 'corAuthors' => [
  474. 'terms' => [
  475. 'field' => 'author_org_list.keyword',
  476. 'order' => [
  477. '_count' => 'desc',
  478. ],
  479. 'size' => 50
  480. ]
  481. ],
  482. 'corOrgs' => [
  483. 'terms' => [
  484. 'field' => 'organization_parsed.keyword',
  485. 'order' => [
  486. '_count' => 'desc'
  487. ],
  488. 'size' => 50
  489. ]
  490. ],
  491. 'docStat' => [
  492. 'terms' => [
  493. 'field' => 'year',
  494. 'order' => [
  495. '_key' => 'asc',
  496. ],
  497. "size" => 50
  498. ],
  499. 'aggs' => [
  500. 'yearCitedCnt' => [
  501. 'sum' => [
  502. 'field' => 'citation_relate_count'
  503. ]
  504. ]
  505. ]
  506. ],
  507. 'keywordCnt' => [
  508. 'terms' => [
  509. 'field' => 'keyword_list.keyword',
  510. 'order' => [
  511. '_count' => 'desc'
  512. ],
  513. 'size' => 20
  514. ]
  515. ]
  516. ]
  517. ]
  518. ];
  519. $client = $this->getEsClient();
  520. $result = $client->search($params);
  521. $newCitedTrend = [];
  522. $citedTrend = $result['aggregations']['docStat']['buckets'];
  523. foreach ($citedTrend as $key => $value) {
  524. $newCitedTrend[$key]['key'] = $value['key'];
  525. $newCitedTrend[$key]['doc_count'] = $value['yearCitedCnt']['value'];
  526. }
  527. $corAuthors = $result['aggregations']['corAuthors']['buckets'];
  528. $nerCorAuthors = [];
  529. foreach ($corAuthors as $key => $value) {
  530. $authorOrg = explode('#', $value['key']);
  531. $nerCorAuthors[$key]['key'] = $authorOrg[0];
  532. $nerCorAuthors[$key]['org'] = $authorOrg[1];
  533. }
  534. $research_topic = $result['aggregations']['keywordCnt']['buckets'];
  535. $authorDetail = [
  536. 'achievement_num' => $result['hits']['total'],
  537. 'citation_frequency' => $result['aggregations']['citedCnt']['value'],
  538. 'cooperation_partner_num' => $result['aggregations']['corAuthorCnt']['value'],
  539. 'cooperation_organization_num' => $result['aggregations']['corOrgCnt']['value'],
  540. 'co_author_list' => $nerCorAuthors,
  541. 'post_trend' => $result['aggregations']['docStat']['buckets'],
  542. 'cited_trend' => $newCitedTrend,
  543. 'research_topic' => $research_topic,
  544. 'co_organization_list' => $result['aggregations']['corOrgs']['buckets'],
  545. 'domain' => array_column($research_topic, 'key')
  546. ];
  547. return $authorDetail[$tag];
  548. }
  549. }