1
1
import { BgmClient , type Search } from 'bgmc' ;
2
+ import { distance } from 'fastest-levenshtein' ;
2
3
3
4
const client = new BgmClient ( fetch ) ;
4
5
@@ -17,7 +18,7 @@ export default defineEventHandler(async (event) => {
17
18
18
19
if ( resp . list && resp . list . length > 0 ) {
19
20
// 获取第一个搜索结果
20
- const foundId = await inferSubject ( resp . list ) ;
21
+ const foundId = await inferSubject ( input , resp . list ) ;
21
22
22
23
if ( foundId ) {
23
24
const [ subject , persons ] = await Promise . all ( [
@@ -47,13 +48,40 @@ export default defineEventHandler(async (event) => {
47
48
return { subject : null , persons : null } ;
48
49
} ) ;
49
50
51
+ /**
52
+ * 使用编辑距离 (levenshtein distance),选择一个标题最相似的 subject
53
+ */
54
+ function selectSubject ( input : string , subjects : Search [ 'list' ] ) {
55
+ const result1 = closest ( input , subjects ! , ( subject ) => subject . name ) ;
56
+ const result2 = closest ( input , subjects ! , ( subject ) => subject . name_cn ) ;
57
+
58
+ return distance ( input , result1 . name ?? '' ) <= distance ( input , result2 . name_cn ?? '' )
59
+ ? result1
60
+ : result2 ;
61
+
62
+ function closest < T > ( str : string , arr : T [ ] , key : ( value : T ) => string | null | undefined ) {
63
+ let min_distance = Infinity ;
64
+ let min_index = 0 ;
65
+ for ( let i = 0 ; i < arr . length ; i ++ ) {
66
+ const name = key ( arr [ i ] ) ;
67
+ if ( name === undefined || name === null ) continue ;
68
+ const dist = distance ( str , name ) ;
69
+ if ( dist < min_distance ) {
70
+ min_distance = dist ;
71
+ min_index = i ;
72
+ }
73
+ }
74
+ return arr [ min_index ] ;
75
+ }
76
+ }
77
+
50
78
/**
51
79
* 1. 使用搜索结果的第一个
52
80
* 2. 如果它是系列中的某一部,则使用系列
53
81
*/
54
- async function inferSubject ( subjects : Search [ 'list' ] ) {
82
+ async function inferSubject ( input : string , subjects : Search [ 'list' ] ) {
55
83
if ( ! subjects ) return undefined ;
56
- const first = subjects [ 0 ] ;
84
+ const first = selectSubject ( input , subjects ) ;
57
85
if ( ! first || ! first . id ) return undefined ;
58
86
59
87
const related = await client . subjectRelated ( first . id ) ;
0 commit comments