ExportPaliWordFrequency.php 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. <?php
  2. namespace App\Console\Commands;
  3. use App\Models\Sentence;
  4. use Illuminate\Console\Attributes\Description;
  5. use Illuminate\Console\Attributes\Signature;
  6. use Illuminate\Console\Command;
  7. #[Signature('export:pali-word-frequency {--limit=0 : 只处理前 N 条记录,0 表示全部(测试用)}')]
  8. #[Description('扫描 channel.type=translation 的句子,统计 [[巴利文]] 单词出现次数并输出 CSV')]
  9. class ExportPaliWordFrequency extends Command
  10. {
  11. /**
  12. * Execute the console command.
  13. */
  14. public function handle(): int
  15. {
  16. $limit = (int) $this->option('limit');
  17. $query = Sentence::type('translation')->select(['uid', 'content'])->orderBy('uid');
  18. $total = $query->count();
  19. $this->info("符合要求的 sentences 总数: {$total}".($limit > 0 ? "(本次仅处理前 {$limit} 条)" : ''));
  20. if ($total === 0) {
  21. $this->warn('没有找到任何记录,退出。');
  22. return 0;
  23. }
  24. if ($limit > 0) {
  25. $query = $query->limit($limit);
  26. }
  27. $wordCounts = [];
  28. $processed = 0;
  29. $matchedSentences = 0;
  30. foreach ($query->cursor() as $sent) {
  31. $processed++;
  32. if (! empty($sent->content) && preg_match_all('/\[\[([^\[\]]+)\]\]/u', $sent->content, $matches) > 0) {
  33. $matchedSentences++;
  34. foreach ($matches[1] as $word) {
  35. $word = trim($word);
  36. if ($word === '') {
  37. continue;
  38. }
  39. $wordCounts[$word] = ($wordCounts[$word] ?? 0) + 1;
  40. }
  41. }
  42. if ($processed % 1000 === 0) {
  43. $this->info("已处理 {$processed}/{$total} 条,其中 {$matchedSentences} 条包含 [[巴利文]],累计发现 ".count($wordCounts).' 个不同单词');
  44. }
  45. }
  46. arsort($wordCounts, SORT_NUMERIC);
  47. $fileName = 'pali-word-frequency-'.date('Ymd-His').($limit > 0 ? "-limit{$limit}" : '').'.csv';
  48. $exportDir = storage_path('app/public/export');
  49. if (! is_dir($exportDir)) {
  50. mkdir($exportDir, 0755, true);
  51. }
  52. $filePath = $exportDir.'/'.$fileName;
  53. $file = fopen($filePath, 'w');
  54. fwrite($file, "\xEF\xBB\xBF");
  55. fputcsv($file, ['word', 'count']);
  56. foreach ($wordCounts as $word => $count) {
  57. fputcsv($file, [$word, $count]);
  58. }
  59. fclose($file);
  60. $this->info("扫描完成:共处理 {$processed} 条记录,{$matchedSentences} 条包含 [[巴利文]],".count($wordCounts).' 个不同单词');
  61. $this->info("CSV 已输出: {$filePath}");
  62. return 0;
  63. }
  64. }