EsService.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. <?php
  2. namespace App\JsonRpc;
  3. use App\Tools\PublicData;
  4. use App\Tools\Result;
  5. use Hyperf\DbConnection\Db;
  6. use Hyperf\RpcServer\Annotation\RpcService;
  7. use Psr\Log\LoggerInterface;
  8. use Psr\Http\Message\ServerRequestInterface;
  9. use Hyperf\Context\Context;
  10. use App\Service\ElasticsearchService;
  11. use Hyperf\Elasticsearch\ClientBuilderFactory;
  12. #[RpcService(name: "EsService", protocol: "jsonrpc-http", server: "jsonrpc-http")]
  13. class EsService implements EsServiceInterface
  14. {
  15. private LoggerInterface $logger;
  16. private ElasticsearchService $elasticsearchService; // 添加 ElasticsearchService 属性
  17. private ClientBuilderFactory $clientBuilderFactory;
  18. private $client; // 添加 Elasticsearch 客户端属性
  19. public function __construct(LoggerInterface $logger, ElasticsearchService $elasticsearchService , ClientBuilderFactory $clientBuilderFactory)
  20. {
  21. $this->logger = $logger;
  22. $this->elasticsearchService = $elasticsearchService; // 注入 ElasticsearchService 实例
  23. $this->clientBuilderFactory = $clientBuilderFactory;
  24. // 创建 Elasticsearch 客户端实例
  25. $builder = $this->clientBuilderFactory->create();
  26. $this->client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  27. }
  28. public function createIndex(array $data): array
  29. {// 获取当前请求的 ServerRequestInterface
  30. $request = Context::get(ServerRequestInterface::class);
  31. var_dump($request->getUri());
  32. // 记录请求数据
  33. $this->logger->info("Received request to createIndex with data: " . json_encode($data));
  34. // 如果在协程环境下创建,则会自动使用协程版的 Handler,非协程环境下无改变
  35. $builder = $this->clientBuilderFactory->create();
  36. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  37. $info = $client->info();
  38. $this->logger->info("es info: " . json_encode($info));
  39. // return Result::success( $info);
  40. $params = [
  41. 'index' => 'articles',
  42. 'body' => [
  43. 'mappings' => [
  44. 'properties' => [
  45. 'id' => ['type' => 'long'],
  46. 'catid' => ['type' => 'integer'],
  47. 'level' => ['type' => 'integer'],
  48. 'title' => ['type' => 'text'],
  49. 'introduce' => ['type' => 'text'],
  50. 'tag' => ['type' => 'keyword'],
  51. 'keyword' => ['type' => 'text'],
  52. 'author' => ['type' => 'keyword'],
  53. 'copyfrom' => ['type' => 'text'],
  54. 'fromurl' => ['type' => 'text'],
  55. 'hits' => ['type' => 'integer'],
  56. 'ip' => ['type' => 'keyword'],
  57. 'status' => ['type' => 'integer'],
  58. 'islink' => ['type' => 'integer'],
  59. 'linkurl' => ['type' => 'text'],
  60. 'imgurl' => ['type' => 'text'],
  61. 'admin_user_id' => ['type' => 'integer'],
  62. 'cat_arr_id' => ['type' => 'text'],
  63. 'created_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss||strict_date_optional_time||epoch_millis'],
  64. 'updated_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss||strict_date_optional_time||epoch_millis'],
  65. 'is_original' => ['type' => 'integer'],
  66. 'content' => ['type' => 'text'],
  67. ],
  68. ],
  69. ],
  70. ];
  71. $response = $client->indices()->create($params);
  72. return Result::success( $response);
  73. // try {
  74. // // 调用 ElasticsearchService 的 createIndex 方法
  75. // $response = $this->elasticsearchService->createIndex();
  76. // $this->logger->info("Index created successfully: " . json_encode($response));
  77. // return Result::success('创建成功', $response);
  78. // } catch (\Exception $e) {
  79. // $this->logger->error("Failed to create index: " . $e->getMessage());
  80. // return Result::error('创建失败', $e->getMessage());
  81. // }
  82. }
  83. public function associateData(array $data): array
  84. {
  85. // 使用注入的 ClientBuilderFactory 创建客户端
  86. $builder = $this->clientBuilderFactory->create();
  87. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  88. $indexName = $data['index'] ?? 'articles';
  89. // 获取所有文章和文章数据
  90. $articles = Db::table('article')->limit(2)->orderBy('id', 'desc')->get();
  91. $articleData = Db::table('article_data')->limit(2)->orderBy('article_id', 'desc')->get();
  92. // 将 article_data 转换为数组,以便快速查找
  93. $articleDataMap = [];
  94. foreach ($articleData as $data) {
  95. $articleDataMap[$data->article_id] = $data;
  96. }
  97. $this->logger->info("articleDataMap: " . json_encode($articleDataMap));
  98. $successCount = 0;
  99. $errorCount = 0;
  100. $errors = [];
  101. foreach ($articles as $article) {
  102. $data = $articleDataMap[$article->id] ?? null;
  103. if ($data) {
  104. $params = [
  105. 'index' => $indexName,
  106. 'id' => $article->id,
  107. 'body' => [
  108. 'id' => $article->id,
  109. 'catid' => $article->catid,
  110. 'level' => $article->level,
  111. 'title' => $article->title,
  112. 'introduce' => $article->introduce,
  113. 'tag' => $article->tag,
  114. 'keyword' => $article->keyword,
  115. 'author' => $article->author,
  116. 'copyfrom' => $article->copyfrom,
  117. 'fromurl' => $article->fromurl,
  118. 'hits' => $article->hits,
  119. 'ip' => $article->ip,
  120. 'status' => $article->status,
  121. 'islink' => $article->islink,
  122. 'linkurl' => $article->linkurl,
  123. 'imgurl' => $article->imgurl,
  124. 'admin_user_id' => $article->admin_user_id,
  125. 'cat_arr_id' => $article->cat_arr_id,
  126. 'created_at' => $article->created_at,
  127. 'updated_at' => $article->updated_at,
  128. 'is_original' => $article->is_original,
  129. 'content' => $data->content,
  130. ],
  131. ];
  132. try {
  133. $response = $client->index($params);
  134. $successCount++;
  135. // 记录成功日志(可选,根据需要)
  136. // $this->logger->info("Data associated successfully: " . json_encode($response));
  137. } catch (\Exception $e) {
  138. $errorCount++;
  139. $errors[] = "Failed to associate data for article ID {$article->id}: " . $e->getMessage();
  140. $this->logger->error("Failed to associate data for article ID {$article->id}: " . $e->getMessage());
  141. }
  142. } else {
  143. $errorCount++;
  144. $errors[] = "No data found for article ID {$article->id}";
  145. $this->logger->error("No data found for article ID {$article->id}");
  146. }
  147. }
  148. if ($errorCount > 0) {
  149. return Result::error("部分数据关联失败", [
  150. 'success_count' => $successCount,
  151. 'error_count' => $errorCount,
  152. 'errors' => $errors,
  153. ]);
  154. }
  155. return Result::success( [
  156. 'success_count' => $successCount,
  157. ]);
  158. }
  159. public function searchIndex(array $data): array
  160. {
  161. // 使用注入的 ClientBuilderFactory 创建客户端
  162. $builder = $this->clientBuilderFactory->create();
  163. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  164. $indexName = $data['index'] ?? 'articles';
  165. $query = $data['query'] ?? [];
  166. $from = $data['from'] ?? 0; // 从哪个文档开始,默认为 0
  167. $size = $data['size'] ?? 10; // 返回的文档数量,默认为 10
  168. $params = [
  169. 'index' => $indexName,
  170. 'body' => [
  171. 'query' => [
  172. 'multi_match' => [
  173. 'query' => $query,
  174. 'fields' => ['*'] // 匹配所有字段
  175. ]
  176. ],
  177. 'from' => $from,
  178. 'size' => $size
  179. ],
  180. ];
  181. try {
  182. $response = $client->search($params);
  183. $this->logger->info("Search successful: " . json_encode($response));
  184. return Result::success( $response);
  185. } catch (\Exception $e) {
  186. $this->logger->error("Failed to search index: " . $e->getMessage());
  187. return Result::error("查询索引失败", $e->getMessage());
  188. }
  189. }
  190. public function deleteIndex(array $data): array
  191. {
  192. $indexName = $data['index'] ?? 'articles';
  193. $builder = $this->clientBuilderFactory->create();
  194. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  195. try {
  196. $response = $client->indices()->delete(['index' => $indexName]);
  197. $this->logger->info("Index {$indexName} deleted successfully: " . json_encode($response));
  198. return Result::success( $response);
  199. } catch (\Exception $e) {
  200. $this->logger->error("Failed to delete index {$indexName}: " . $e->getMessage());
  201. throw new \RuntimeException("删除索引失败: " . $e->getMessage(), 0, $e);
  202. return Result::error("删除索引失败".$e->getMessage());
  203. }
  204. }
  205. public function indexExists($index)
  206. {
  207. $indexName = $data['index'] ?? 'articles';
  208. $builder = $this->clientBuilderFactory->create();
  209. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  210. try {
  211. return $client->indices()->exists(['index' => $index]);
  212. } catch (\Exception $e) {
  213. $this->logger->error("Failed to check if index {$index} exists: " . $e->getMessage());
  214. throw new \RuntimeException("检查索引是否存在失败: " . $e->getMessage(), 0, $e);
  215. }
  216. }
  217. public function updateIndex(array $data): array
  218. {
  219. $newMapping = $data['mapping'] ?? [];
  220. $builder = $this->clientBuilderFactory->create();
  221. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  222. $indexName = $data['index'] ?? 'articles';
  223. if (empty($newMapping)) {
  224. return Result::error("Mapping data is required", "No mapping data provided");
  225. }
  226. try {
  227. $response = $client->indices()->putMapping([
  228. 'index' => $indexName,
  229. 'body' => [
  230. 'properties' => $newMapping
  231. ]
  232. ]);
  233. $this->logger->info("Successfully updated index {$indexName}: " . json_encode($response));
  234. return Result::success($response);
  235. } catch (\Exception $e) {
  236. $this->logger->error("Failed to update index {$indexName}: " . $e->getMessage());
  237. throw new \RuntimeException("更新索引失败: " . $e->getMessage(), 0, $e);
  238. }
  239. }
  240. public function renameIndex(array $data): array
  241. {
  242. $oldIndexName = $data['old_index'] ?? 'articles_v2';
  243. $newIndexName = $data['new_index'] ?? 'articles';
  244. $builder = $this->clientBuilderFactory->create();
  245. $client = $builder->setHosts(['http://127.0.0.1:9200'])->build();
  246. $indexName = $data['index'] ?? 'articles';
  247. $params = [
  248. 'body' => [
  249. 'actions' => [
  250. [
  251. 'rename' => [
  252. 'old_index' => $oldIndexName,
  253. 'new_index' => $newIndexName
  254. ]
  255. ]
  256. ]
  257. ]
  258. ];
  259. try {
  260. $response = $client->indices()->updateAliases($params);
  261. $this->logger->info("Index renamed successfully: " . json_encode($response));
  262. return Result::success( $response);
  263. } catch (\Exception $e) {
  264. $this->logger->error("Failed to rename index: " . $e->getMessage());
  265. return Result::error( $e->getMessage());
  266. }
  267. }
  268. public function deleteData(array $data): array
  269. {
  270. return Result::success( '成功');
  271. }
  272. public function updateData(array $data): array
  273. {
  274. return Result::success( '成功');
  275. }
  276. }