فهرست منبع

Merge pull request #2443 from visuddhinanda/development

Development
visuddhinanda 1 روز پیش
والد
کامیت
42ede72565

+ 63 - 0
api-v13/app/Console/Commands/PaliQueryHealthCheck.php

@@ -0,0 +1,63 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Services\OpenSearchService;
+use Exception;
+use Illuminate\Console\Attributes\Description;
+use Illuminate\Console\Attributes\Signature;
+use Illuminate\Console\Command;
+
+/**
+ * Check whether the pali_synonyms dictionary is applied for a given word
+ *
+ * Usage:
+ *   php artisan app:pali-query-health-check          # defaults to "dhamma"
+ *   php artisan app:pali-query-health-check dhamma    # custom word
+ */
+#[Signature('app:pali-query-health-check {word? : Pali word to check, defaults to dhamma}')]
+#[Description('Check whether the pali_synonyms dictionary is applied for a given word via the OpenSearch _analyze API')]
+class PaliQueryHealthCheck extends Command
+{
+    /**
+     * Execute the console command.
+     *
+     * @param  OpenSearchService  $service
+     * @return int Command::SUCCESS | Command::FAILURE
+     */
+    public function handle(OpenSearchService $service): int
+    {
+        $word = $this->argument('word') ?? 'dhamma';
+
+        $this->info("Checking synonym expansion for [{$word}]...");
+
+        try {
+            $tokens = $service->pali_query_health_check($word);
+        } catch (Exception $e) {
+            $this->error('Check failed: '.$e->getMessage());
+
+            return self::FAILURE;
+        }
+
+        if (empty($tokens)) {
+            $this->warn('No tokens returned. Please check that the index exists and the analyzer is configured correctly.');
+
+            return self::FAILURE;
+        }
+
+        $this->table(
+            ['#', 'Token'],
+            collect($tokens)->values()->map(fn ($token, $i) => [$i + 1, $token])->toArray()
+        );
+
+        $expanded = count($tokens) > 1;
+
+        if ($expanded) {
+            $this->info("✅ Synonym dictionary is active — [{$word}] expanded into ".count($tokens).' token(s).');
+        } else {
+            $this->warn("⚠️  [{$word}] did not expand into any synonyms. Check that the entry exists in pali_synonyms.txt, or that the index has reloaded the file.");
+        }
+
+        return self::SUCCESS;
+    }
+}

+ 41 - 0
api-v13/app/Services/OpenSearchService.php

@@ -1168,4 +1168,45 @@ class OpenSearchService
             'id' => $id,
             'id' => $id,
         ]);
         ]);
     }
     }
+
+    /**
+     * 校验 pali_synonyms 同义词词典是否对指定词生效
+     *
+     * 通过 OpenSearch _analyze API,用当前索引的 pali_query_analyzer
+     * 对输入文本做实时分析,返回展开后的全部 token(含原词与同义词)。
+     * 可用于快速确认 analysis/pali_synonyms.txt 中的某一行是否已生效
+     * (例如 dhamma,dharma,法 => dhamma 是否真的展开出 dharma、法)。
+     *
+     * @param  string  $text  待检测的巴利词,例如 "dhamma"
+     * @return array<int, string> 分析器输出的 token 文本数组(已去重,保留原始顺序)
+     *
+     * @throws Exception 索引不存在或 OpenSearch 调用失败时抛出
+     *
+     * @example
+     *   $service->pali_query_health_check('dhamma');
+     *   // => ['dhamma', 'dharma', '法']
+     */
+    public function pali_query_health_check(string $text): array
+    {
+        $index = config('mint.opensearch.index');
+
+        if (! $this->client->indices()->exists(['index' => $index])) {
+            throw new Exception("Index [$index] does not exist.");
+        }
+
+        $response = $this->client->indices()->analyze([
+            'index' => $index,
+            'body' => [
+                'analyzer' => 'pali_query_analyzer',
+                'text' => $text,
+            ],
+        ]);
+
+        $tokens = array_map(
+            fn ($token) => $token['token'] ?? '',
+            $response['tokens'] ?? []
+        );
+
+        return array_values(array_unique(array_filter($tokens, fn ($t) => $t !== '')));
+    }
 }
 }

+ 1 - 1
api-v13/config/cache.php

@@ -112,7 +112,7 @@ return [
     |
     |
     */
     */
 
 
-    'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')) . '-cache-'),
+    'prefix' => env('CACHE_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-cache-'),
 
 
     /*
     /*
     |--------------------------------------------------------------------------
     |--------------------------------------------------------------------------

+ 1 - 1
api-v13/config/database.php

@@ -149,7 +149,7 @@ return [
 
 
         'options' => [
         'options' => [
             'cluster' => env('REDIS_CLUSTER', 'redis'),
             'cluster' => env('REDIS_CLUSTER', 'redis'),
-            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_database_'),
+            'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
             'persistent' => env('REDIS_PERSISTENT', false),
             'persistent' => env('REDIS_PERSISTENT', false),
         ],
         ],
 
 

+ 1 - 1
api-v13/config/filesystems.php

@@ -41,7 +41,7 @@ return [
         'public' => [
         'public' => [
             'driver' => 'local',
             'driver' => 'local',
             'root' => storage_path('app/public'),
             'root' => storage_path('app/public'),
-            'url' => rtrim(env('APP_URL', 'http://localhost'), '/') . '/storage',
+            'url' => rtrim(env('APP_URL', 'http://localhost'), '/').'/storage',
             'visibility' => 'public',
             'visibility' => 'public',
             'throw' => false,
             'throw' => false,
             'report' => false,
             'report' => false,

+ 3 - 3
api-v13/config/logging.php

@@ -126,15 +126,15 @@ return [
         'emergency' => [
         'emergency' => [
             'path' => storage_path('logs/laravel.log'),
             'path' => storage_path('logs/laravel.log'),
         ],
         ],
-	'stdout' => [
+        'stdout' => [
             'driver' => 'monolog',
             'driver' => 'monolog',
             'level' => env('LOG_LEVEL', 'debug'),
             'level' => env('LOG_LEVEL', 'debug'),
-            'handler' => Monolog\Handler\StreamHandler::class,
+            'handler' => StreamHandler::class,
             'formatter' => env('LOG_STDERR_FORMATTER'),
             'formatter' => env('LOG_STDERR_FORMATTER'),
             'with' => [
             'with' => [
                 'stream' => 'php://stdout',
                 'stream' => 'php://stdout',
             ],
             ],
-	],
+        ],
 
 
     ],
     ],
 
 

+ 83 - 85
api-v13/config/taxonomy.php

@@ -26,227 +26,225 @@ $allTags = collect(config('taxonomy'))
 
 
 return [
 return [
     [
     [
-        'id'    => 'vinaya',
+        'id' => 'vinaya',
         'label' => '律学',
         'label' => '律学',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'āpatti',
+                'id' => 'āpatti',
                 'label' => '戒条罪类',
                 'label' => '戒条罪类',
-                'tags'  => ['波罗夷', '僧残', '不定', '舍堕', '单堕', '悔过', '众学', '灭诤', '比库戒', '比库尼戒', '学处', '犯罪', '无犯', '违犯条件'],
+                'tags' => ['波罗夷', '僧残', '不定', '舍堕', '单堕', '悔过', '众学', '灭诤', '比库戒', '比库尼戒', '学处', '犯罪', '无犯', '违犯条件'],
             ],
             ],
             [
             [
-                'id'    => 'vinayakamma',
+                'id' => 'vinayakamma',
                 'label' => '僧羯磨',
                 'label' => '僧羯磨',
-                'tags'  => ['羯磨',  '结界', '布萨', '自恣', '受具足', '出家', '僧团', '惩罚羯磨'],
+                'tags' => ['羯磨',  '结界', '布萨', '自恣', '受具足', '出家', '僧团', '惩罚羯磨'],
             ],
             ],
             [
             [
-                'id'    => 'monastic-life',
+                'id' => 'monastic-life',
                 'label' => '僧侣生活与器具',
                 'label' => '僧侣生活与器具',
-                'tags'  => ['三衣', '钵', '住处', '精舍', '雨安居', '迦提那衣', '头陀行', '乞食', '日用器具', '净食'],
+                'tags' => ['三衣', '钵', '住处', '精舍', '雨安居', '迦提那衣', '头陀行', '乞食', '日用器具', '净食'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'dhamma',
+        'id' => 'dhamma',
         'label' => '法义',
         'label' => '法义',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'basic-doctrine',
+                'id' => 'basic-doctrine',
                 'label' => '基本教义',
                 'label' => '基本教义',
-                'tags'  => ['四圣谛',  '缘起', '十二缘起', '三法印', '五蕴', '三宝', '八正道',],
+                'tags' => ['四圣谛',  '缘起', '十二缘起', '三法印', '五蕴', '三宝', '八正道'],
             ],
             ],
             [
             [
-                'id'    => 'kamma-samsara',
+                'id' => 'kamma-samsara',
                 'label' => '业与轮回',
                 'label' => '业与轮回',
-                'tags'  => ['业', '善业', '不善业', '无记业', '业报', '轮回', '结生', '再生', '三界轮转'],
+                'tags' => ['业', '善业', '不善业', '无记业', '业报', '轮回', '结生', '再生', '三界轮转'],
             ],
             ],
             [
             [
-                'id'    => 'nibbana',
+                'id' => 'nibbana',
                 'label' => '涅槃与解脱',
                 'label' => '涅槃与解脱',
-                'tags'  => ['涅槃', '有余涅槃', '无余涅槃', '解脱', '道', '果', '烦恼断除', '结', '漏'],
+                'tags' => ['涅槃', '有余涅槃', '无余涅槃', '解脱', '道', '果', '烦恼断除', '结', '漏'],
             ],
             ],
             [
             [
-                'id'    => 'citta',
+                'id' => 'citta',
                 'label' => '心路与心类',
                 'label' => '心路与心类',
-                'tags'  => ['欲界心', '色界心', '无色界心', '出世间心', '善心', '不善心', '无记心', '心路', '五门心路', '意门心路', '速行', '有分',],
+                'tags' => ['欲界心', '色界心', '无色界心', '出世间心', '善心', '不善心', '无记心', '心路', '五门心路', '意门心路', '速行', '有分'],
             ],
             ],
             [
             [
-                'id'    => 'cetasika',
+                'id' => 'cetasika',
                 'label' => '心所法',
                 'label' => '心所法',
-                'tags'  => ['遍一切心心所', '杂心所', '不善心所', '美心所', '贪', '嗔', '痴', '慢', '邪见', '掉举', '信', '念', '慧', '悲', '喜', '舍'],
+                'tags' => ['遍一切心心所', '杂心所', '不善心所', '美心所', '贪', '嗔', '痴', '慢', '邪见', '掉举', '信', '念', '慧', '悲', '喜', '舍'],
             ],
             ],
             [
             [
-                'id'    => 'rupa',
+                'id' => 'rupa',
                 'label' => '色法',
                 'label' => '色法',
-                'tags'  => ['四大种', '地界', '水界', '火界', '风界', '净色', '所造色', '色聚', '业生色', '心生色', '时节生色', '食生色', '真实色', '非真实色'],
+                'tags' => ['四大种', '地界', '水界', '火界', '风界', '净色', '所造色', '色聚', '业生色', '心生色', '时节生色', '食生色', '真实色', '非真实色'],
             ],
             ],
             [
             [
-                'id'    => 'paccaya',
+                'id' => 'paccaya',
                 'label' => '缘起与发趣法',
                 'label' => '缘起与发趣法',
-                'tags'  => ['二十四缘', '因缘',],
+                'tags' => ['二十四缘', '因缘'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
-
     [
     [
-        'id'    => 'bhavana',
+        'id' => 'bhavana',
         'label' => '禅修',
         'label' => '禅修',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'samatha',
+                'id' => 'samatha',
                 'label' => '止禅',
                 'label' => '止禅',
-                'tags'  => ['遍禅', '不净观', '随念', '四梵住',  '入出息念', '四界差别', '禅相', '取相', '似相', '近行定', '安止定', '禅那', '禅支', '无色定'],
+                'tags' => ['遍禅', '不净观', '随念', '四梵住',  '入出息念', '四界差别', '禅相', '取相', '似相', '近行定', '安止定', '禅那', '禅支', '无色定'],
             ],
             ],
             [
             [
-                'id'    => 'vipassana',
+                'id' => 'vipassana',
                 'label' => '观禅',
                 'label' => '观禅',
-                'tags'  => ['名色分别', '观智', '生灭智', '坏灭智', '怖畏智', '厌离智', '行舍智', '道智', '果智', '毘婆舍那', '三相', '无常随观', '苦随观', '无我随观', '刹那定'],
+                'tags' => ['名色分别', '观智', '生灭智', '坏灭智', '怖畏智', '厌离智', '行舍智', '道智', '果智', '毘婆舍那', '三相', '无常随观', '苦随观', '无我随观', '刹那定'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
-
     [
     [
-        'id'    => 'patha',
+        'id' => 'patha',
         'label' => '典籍',
         'label' => '典籍',
-        'tags'  => ['经名', '品名', '篇名'],
-        'subs'  => [
+        'tags' => ['经名', '品名', '篇名'],
+        'subs' => [
             [
             [
-                'id'    => 'suttapitaka',
+                'id' => 'suttapitaka',
                 'label' => '经藏',
                 'label' => '经藏',
-                'tags'  => ['长部', '中部', '相应部', '增支部', '小部',],
+                'tags' => ['长部', '中部', '相应部', '增支部', '小部'],
             ],
             ],
             [
             [
-                'id'    => 'abhidhammapitaka',
+                'id' => 'abhidhammapitaka',
                 'label' => '论藏',
                 'label' => '论藏',
-                'tags'  => ['法集论', '分别论', '界论', '人施设论', '论事', '双论'],
+                'tags' => ['法集论', '分别论', '界论', '人施设论', '论事', '双论'],
             ],
             ],
             [
             [
-                'id'    => 'vinayapitaka',
+                'id' => 'vinayapitaka',
                 'label' => '律藏',
                 'label' => '律藏',
-                'tags'  => ['经分别', '篇章', '附随'],
+                'tags' => ['经分别', '篇章', '附随'],
             ],
             ],
             [
             [
-                'id'    => 'vanna',
+                'id' => 'vanna',
                 'label' => '注释',
                 'label' => '注释',
-                'tags'  => ['义注', '复注', '根本复注', '再复注'],
+                'tags' => ['义注', '复注', '根本复注', '再复注'],
             ],
             ],
             [
             [
-                'id'    => 'anna',
+                'id' => 'anna',
                 'label' => '藏外',
                 'label' => '藏外',
-                'tags'  => ['清净道论', '历史', '文法书'],
+                'tags' => ['清净道论', '历史', '文法书'],
             ],
             ],
             [
             [
-                'id'    => 'vatthu',
+                'id' => 'vatthu',
                 'label' => '故事类',
                 'label' => '故事类',
-                'tags'  => ['本生', '佛种姓', '譬喻', '天宫事', '饿鬼事'],
+                'tags' => ['本生', '佛种姓', '譬喻', '天宫事', '饿鬼事'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'cosmology',
+        'id' => 'cosmology',
         'label' => '世界观',
         'label' => '世界观',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'akasaloka',
+                'id' => 'akasaloka',
                 'label' => '空间世间',
                 'label' => '空间世间',
-                'tags'  => ['欲界', '色界', '无色界', '欲界天', '梵天界', '净居天', '人间', '有情居', '天界层次'],
+                'tags' => ['欲界', '色界', '无色界', '欲界天', '梵天界', '净居天', '人间', '有情居', '天界层次'],
             ],
             ],
             [
             [
-                'id'    => 'apaya',
+                'id' => 'apaya',
                 'label' => '地狱与恶趣',
                 'label' => '地狱与恶趣',
-                'tags'  => ['地狱',  '饿鬼界', '畜生界', '阿修罗界', '四恶趣'],
+                'tags' => ['地狱',  '饿鬼界', '畜生界', '阿修罗界', '四恶趣'],
             ],
             ],
             [
             [
-                'id'    => 'amanussa',
+                'id' => 'amanussa',
                 'label' => '神灵与非人',
                 'label' => '神灵与非人',
-                'tags'  => ['天神', '梵天', '夜叉', '龙族', '乾达婆', '非人', '护法神'],
+                'tags' => ['天神', '梵天', '夜叉', '龙族', '乾达婆', '非人', '护法神'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'puggala',
+        'id' => 'puggala',
         'label' => '人名',
         'label' => '人名',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'buddha',
+                'id' => 'buddha',
                 'label' => '佛',
                 'label' => '佛',
-                'tags'  => ['佛名', '过去佛', '二十八佛', '独觉佛', '菩萨'],
+                'tags' => ['佛名', '过去佛', '二十八佛', '独觉佛', '菩萨'],
             ],
             ],
             [
             [
-                'id'    => 'pabbajita',
+                'id' => 'pabbajita',
                 'label' => '出家弟子',
                 'label' => '出家弟子',
-                'tags'  => ['上首弟子', '大弟子', '比库弟子', '比库尼弟子', '沙弥', '沙弥尼', '在学尼'],
+                'tags' => ['上首弟子', '大弟子', '比库弟子', '比库尼弟子', '沙弥', '沙弥尼', '在学尼'],
             ],
             ],
             [
             [
-                'id'    => 'gahapati',
+                'id' => 'gahapati',
                 'label' => '在家人',
                 'label' => '在家人',
-                'tags'  => ['男居士', '女居士', '护法者', '国王', '婆罗门', '施主', '转轮圣王', '王后', '大长者'],
+                'tags' => ['男居士', '女居士', '护法者', '国王', '婆罗门', '施主', '转轮圣王', '王后', '大长者'],
             ],
             ],
             [
             [
-                'id'    => 'titthiya',
+                'id' => 'titthiya',
                 'label' => '外道',
                 'label' => '外道',
-                'tags'  => ['外道名'],
+                'tags' => ['外道名'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'padesa',
+        'id' => 'padesa',
         'label' => '地名',
         'label' => '地名',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'gama',
+                'id' => 'gama',
                 'label' => '人类聚落',
                 'label' => '人类聚落',
-                'tags'  => ['十六大国', '国家', '村落', '市镇', '寺院名'],
+                'tags' => ['十六大国', '国家', '村落', '市镇', '寺院名'],
             ],
             ],
             [
             [
-                'id'    => 'udaka',
+                'id' => 'udaka',
                 'label' => '水系',
                 'label' => '水系',
-                'tags'  => ['河流', '湖泊', '海洋'],
+                'tags' => ['河流', '湖泊', '海洋'],
             ],
             ],
             [
             [
-                'id'    => 'pabbata',
+                'id' => 'pabbata',
                 'label' => '山岳',
                 'label' => '山岳',
-                'tags'  => ['山名', '山脉'],
+                'tags' => ['山名', '山脉'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'bhuta',
+        'id' => 'bhuta',
         'label' => '动植物',
         'label' => '动植物',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'tiracchana',
+                'id' => 'tiracchana',
                 'label' => '动物',
                 'label' => '动物',
-                'tags'  => ['兽类', '鸟类', '爬行类', '水生动物', '昆虫', '神话动物', '龙族', '金翅鸟', '畜养动物', '野生动物'],
+                'tags' => ['兽类', '鸟类', '爬行类', '水生动物', '昆虫', '神话动物', '龙族', '金翅鸟', '畜养动物', '野生动物'],
             ],
             ],
             [
             [
-                'id'    => 'bhutagama',
+                'id' => 'bhutagama',
                 'label' => '植物',
                 'label' => '植物',
-                'tags'  => ['树木', '花卉', '草药', '粮食作物', '果实', '菩提树类'],
+                'tags' => ['树木', '花卉', '草药', '粮食作物', '果实', '菩提树类'],
             ],
             ],
         ],
         ],
     ],
     ],
 
 
     [
     [
-        'id'    => 'saddaniti',
+        'id' => 'saddaniti',
         'label' => '巴利语言与语法',
         'label' => '巴利语言与语法',
-        'subs'  => [
+        'subs' => [
             [
             [
-                'id'    => 'grammar-terms',
+                'id' => 'grammar-terms',
                 'label' => '语法术语',
                 'label' => '语法术语',
-                'tags'  => ['名词', '动词', '形容词', '副词', '格', '数', '性', '时态', '语式', '复合词类型', '前缀', '后缀'],
+                'tags' => ['名词', '动词', '形容词', '副词', '格', '数', '性', '时态', '语式', '复合词类型', '前缀', '后缀'],
             ],
             ],
             [
             [
-                'id'    => 'grammar-abbrev',
+                'id' => 'grammar-abbrev',
                 'label' => '语法缩写与标注',
                 'label' => '语法缩写与标注',
-                'tags'  => ['词性标注', '格标注', '语态标注', '使役态', '引用标记', '出处标注'],
+                'tags' => ['词性标注', '格标注', '语态标注', '使役态', '引用标记', '出处标注'],
             ],
             ],
         ],
         ],
     ],
     ],