Просмотр исходного кода

add APP_OPENSEARCH_SYNONYMS_PATH

visuddhinanda 3 дней назад
Родитель
Сommit
4b1b8e04de

+ 2 - 0
api-v13/.env.example

@@ -75,3 +75,5 @@ JWT_SECRETS_KEY=
 
 # 运维接口令牌 /api/ops/*
 APP_OPS_TOKEN=
+
+APP_OPENSEARCH_SYNONYMS_PATH=""

+ 15 - 16
api-v13/app/Console/Commands/ExportPaliSynonyms.php

@@ -2,11 +2,12 @@
 
 namespace App\Console\Commands;
 
-use App\Http\Api\DictApi;
+use Illuminate\Console\Command;
+use Illuminate\Support\Str;
+
 use App\Models\DhammaTerm;
 use App\Models\UserDict;
 use App\Services\OpenSearchService;
-use Illuminate\Console\Command;
 
 class ExportPaliSynonyms extends Command
 {
@@ -54,8 +55,8 @@ class ExportPaliSynonyms extends Command
         $dictId[] = DictApi::getSysDict('system_regular');
         $dictId[] = DictApi::getSysDict('robot_compound');
 */
-        $filename = $this->option('output');
-        $fp = fopen($filename, 'w') or exit('Unable to open file!');
+        $filename =  $this->option('output');
+        $fp = fopen(Str::finish(config('mint.opensearch.config.synonyms_path'), '/') . $filename, 'w') or exit('Unable to open file!');
 
         $parents = UserDict::select('parent')
             ->whereNotNull('parent')
@@ -81,7 +82,7 @@ class ExportPaliSynonyms extends Command
             foreach ($teams as $term) {
                 $wordsList[$term->meaning] = 1;
             }
-            $this->info("[{$parent->parent}] ".count($words).' team='.count($teams));
+            $this->info("[{$parent->parent}] " . count($words) . ' team=' . count($teams));
             // 合并 $parent->parent, $words->word, $team->meaning 为一个字符串数组
             $combinedArray = [];
             $combinedArray[] = $parent->parent;
@@ -113,18 +114,16 @@ class ExportPaliSynonyms extends Command
         // 关闭文件
         fclose($fp);
 
-        // 写index.json
-        $info = [
-            'index' => config('mint.opensearch.index'),
-            'pali_synonyms' => app(OpenSearchService::class)->getPaliSynonymsSetting(),
-        ];
-        file_put_contents(
-            $this->changeExtensionToJson($filename),
-            json_encode($info, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
-        );
         $this->info("过滤掉非法 term {$droppedTerms} 个,整行丢弃 {$droppedLines} 行。");
+
+        //update opensearch
+        $this->info('update opensearch synonyms');
+        $result = app(OpenSearchService::class)->updatePaliSynonymsPath($filename);
+        $this->info(json_encode($result, JSON_PRETTY_PRINT));
+
         $this->info('done');
 
+
         return 0;
     }
 
@@ -188,9 +187,9 @@ class ExportPaliSynonyms extends Command
         $filename = $pathInfo['filename'] ?? '';
 
         // 如果目录不是根目录,则添加目录分隔符
-        $dirname = rtrim($dirname, DIRECTORY_SEPARATOR).DIRECTORY_SEPARATOR;
+        $dirname = rtrim($dirname, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
 
         // 构建新路径
-        return $dirname.$filename.'.json';
+        return $dirname . $filename . '.json';
     }
 }

+ 20 - 19
api-v13/app/Services/OpenSearchService.php

@@ -8,8 +8,11 @@ use Exception;
 use GuzzleHttp\Client;
 use Illuminate\Support\Facades\Cache;
 use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Str;
+
 use OpenSearch\GuzzleClientFactory;
 
+
 class OpenSearchService
 {
     protected $client;
@@ -392,12 +395,12 @@ class OpenSearchService
     {
         try {
             $info = $this->client->info();
-            $message = 'OpenSearch 连接成功: '.json_encode($info['version']['number']);
+            $message = 'OpenSearch 连接成功: ' . json_encode($info['version']['number']);
             Log::info($message);
 
             return [true, $message];
         } catch (Exception $e) {
-            $message = 'OpenSearch 连接失败: '.$e->getMessage();
+            $message = 'OpenSearch 连接失败: ' . $e->getMessage();
             Log::error($message);
 
             return [false, $message];
@@ -491,11 +494,9 @@ class OpenSearchService
      * @example
      *   $service->updatePaliSynonymsPath('20260731');
      */
-    public function updatePaliSynonymsPath(string $version): array
+    public function updatePaliSynonymsPath(string $filename): array
     {
-        if (! preg_match('/^[A-Za-z0-9._-]+$/', $version)) {
-            throw new Exception("Invalid synonyms version [$version].");
-        }
+
 
         $index = config('mint.opensearch.index');
 
@@ -503,7 +504,7 @@ class OpenSearchService
             throw new Exception("Index [$index] does not exist.");
         }
 
-        $path = "/var/lib/opensearch/analysis/pali_synonyms-{$version}.txt";
+        $path = Str::finish(config('mint.opensearch.config.synonyms_path'), '/') . $filename;
 
         Log::debug('OpenSearchService::updatePaliSynonymsPath', [
             'index' => $index,
@@ -878,7 +879,7 @@ class OpenSearchService
     {
         $fields = [];
         foreach ($this->weights['fuzzy'] as $field => $weight) {
-            $fields[] = $field.'^'.$weight;
+            $fields[] = $field . '^' . $weight;
         }
 
         return [
@@ -909,7 +910,7 @@ class OpenSearchService
             if (in_array($field, ['fuzzy_ratio', 'semantic_ratio'])) {
                 continue;
             }
-            $fuzzyFields[] = $field.'^'.$weight;
+            $fuzzyFields[] = $field . '^' . $weight;
         }
 
         $fuzzyPart = [
@@ -982,12 +983,12 @@ class OpenSearchService
             throw new Exception('请在 .env 设置 OPENAI_API_KEY');
         }
 
-        $cacheKey = 'embedding:'.md5($text);
+        $cacheKey = 'embedding:' . md5($text);
 
         return Cache::remember($cacheKey, now()->addDays(7), function () use ($text) {
             $response = $this->http->post('embeddings', [
                 'headers' => [
-                    'Authorization' => 'Bearer '.$this->openaiApiKey,
+                    'Authorization' => 'Bearer ' . $this->openaiApiKey,
                     'Content-Type' => 'application/json',
                 ],
                 'json' => [
@@ -999,7 +1000,7 @@ class OpenSearchService
             $json = json_decode((string) $response->getBody(), true);
 
             if (empty($json['data'][0]['embedding'])) {
-                throw new Exception('OpenAI embedding 返回异常: '.json_encode($json));
+                throw new Exception('OpenAI embedding 返回异常: ' . json_encode($json));
             }
 
             return $json['data'][0]['embedding'];
@@ -1017,7 +1018,7 @@ class OpenSearchService
      */
     public function clearEmbeddingCache(string $text): bool
     {
-        $cacheKey = 'embedding:'.md5($text);
+        $cacheKey = 'embedding:' . md5($text);
 
         return Cache::forget($cacheKey);
     }
@@ -1102,7 +1103,7 @@ class OpenSearchService
         // 过滤无效字段
         $searchFields = array_values(array_filter(
             $searchFields,
-            fn ($field) => isset($fieldMap[$field])
+            fn($field) => isset($fieldMap[$field])
         ));
 
         if (empty($searchFields)) {
@@ -1112,7 +1113,7 @@ class OpenSearchService
         // 构建 suggest DSL
         $suggests = [];
         foreach ($searchFields as $field) {
-            $suggests[$field.'_suggest'] = [
+            $suggests[$field . '_suggest'] = [
                 'prefix' => $query,
                 'completion' => [
                     'field' => $fieldMap[$field],
@@ -1136,7 +1137,7 @@ class OpenSearchService
         // 整理结果,附加来源字段
         $results = [];
         foreach ($searchFields as $field) {
-            $options = $response['suggest'][$field.'_suggest'][0]['options'] ?? [];
+            $options = $response['suggest'][$field . '_suggest'][0]['options'] ?? [];
 
             foreach ($options as $opt) {
                 $results[] = [
@@ -1150,7 +1151,7 @@ class OpenSearchService
         }
 
         // 按分数降序排序
-        usort($results, fn ($a, $b) => $b['score'] <=> $a['score']);
+        usort($results, fn($a, $b) => $b['score'] <=> $a['score']);
 
         return $results;
     }
@@ -1203,10 +1204,10 @@ class OpenSearchService
         ]);
 
         $tokens = array_map(
-            fn ($token) => $token['token'] ?? '',
+            fn($token) => $token['token'] ?? '',
             $response['tokens'] ?? []
         );
 
-        return array_values(array_unique(array_filter($tokens, fn ($t) => $t !== '')));
+        return array_values(array_unique(array_filter($tokens, fn($t) => $t !== '')));
     }
 }

+ 2 - 0
api-v13/config/mint.php

@@ -176,6 +176,8 @@ return [
             'username' => env('OPENSEARCH_USERNAME', ''),
             'password' => env('OPENSEARCH_PASSWORD', ''),
             'ssl_verification' => env('OPENSEARCH_SSL_VERIFICATION', false),
+            'synonyms_path' => env('APP_OPENSEARCH_SYNONYMS_PATH', '/opt/opensearch/config/analysis'),
+
         ],
 
     ],