lib/search/word: order english queries by score

This commit is contained in:
2025-05-23 15:28:00 +02:00
parent f819280268
commit 6eee49d2d1
2 changed files with 160 additions and 65 deletions

View File

@@ -86,6 +86,135 @@ SearchMode _determineSearchMode(String word) {
]
);
Future<List<ScoredEntryId>> _queryKanji(
DatabaseExecutor connection,
String word,
int pageSize,
int? offset,
) {
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.kanjiElement,
word,
pageSize: pageSize,
);
return connection.rawQuery(query, args).then((result) => result
.map((row) => ScoredEntryId(
row['entryId'] as int,
row['score'] as int,
))
.toList());
}
Future<int> _queryKanjiCount(
DatabaseExecutor connection,
String word,
) {
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.kanjiElement,
word,
countOnly: true,
);
return connection.rawQuery(query, args).then((result) => result.first['count'] as int);
}
Future<List<ScoredEntryId>> _queryKana(
DatabaseExecutor connection,
String word,
int pageSize,
int? offset,
) {
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.readingElement,
word,
pageSize: pageSize,
);
return connection.rawQuery(query, args).then((result) => result
.map((row) => ScoredEntryId(
row['entryId'] as int,
row['score'] as int,
))
.toList());
}
Future<int> _queryKanaCount(
DatabaseExecutor connection,
String word,
) {
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.readingElement,
word,
countOnly: true,
);
return connection.rawQuery(query, args).then((result) => result.first['count'] as int);
}
Future<List<ScoredEntryId>> _queryEnglish(
DatabaseExecutor connection,
String word,
int pageSize,
int? offset,
) async {
final result = await connection.rawQuery(
'''
SELECT
"${JMdictTableNames.sense}"."entryId",
MAX("JMdict_EntryScore"."score")
+ (("${JMdictTableNames.senseGlossary}"."phrase" = ? AND "${JMdictTableNames.sense}"."orderNum" = 1) * 50)
+ (("${JMdictTableNames.senseGlossary}"."phrase" = ? AND "${JMdictTableNames.sense}"."orderNum" = 2) * 30)
+ (("${JMdictTableNames.senseGlossary}"."phrase" = ?) * 20)
as "score"
FROM "${JMdictTableNames.senseGlossary}"
JOIN "${JMdictTableNames.sense}" USING ("senseId")
JOIN "JMdict_EntryScore" USING ("entryId")
WHERE "${JMdictTableNames.senseGlossary}"."phrase" LIKE ?
GROUP BY "JMdict_EntryScore"."entryId"
ORDER BY
"score" DESC,
"${JMdictTableNames.sense}"."entryId" ASC
LIMIT ?
OFFSET ?
'''
.trim(),
[
word,
'%$word%',
'%$word%',
'%$word%',
pageSize,
offset,
],
);
return result
.map((row) => ScoredEntryId(
row['entryId'] as int,
row['score'] as int,
))
.toList();
}
Future<int> _queryEnglishCount(
DatabaseExecutor connection,
String word,
) async {
final result = await connection.rawQuery(
'''
SELECT
COUNT(DISTINCT "${JMdictTableNames.sense}"."entryId") AS "count"
FROM "${JMdictTableNames.senseGlossary}"
JOIN "${JMdictTableNames.sense}" USING ("senseId")
WHERE "${JMdictTableNames.senseGlossary}"."phrase" LIKE ?
'''
.trim(),
[
'%$word%',
],
);
return result.first['count'] as int;
}
Future<List<ScoredEntryId>> fetchEntryIds(
DatabaseExecutor connection,
String word,
@@ -105,56 +234,30 @@ Future<List<ScoredEntryId>> fetchEntryIds(
late final List<ScoredEntryId> entryIds;
switch (searchMode) {
case SearchMode.Kanji:
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.kanjiElement,
entryIds = await _queryKanji(
connection,
word,
pageSize: pageSize,
pageSize,
offset,
);
entryIds = (await connection.rawQuery(query, args))
.map((row) => ScoredEntryId(
row['entryId'] as int,
row['score'] as int,
))
.toList();
break;
case SearchMode.Kana:
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.readingElement,
entryIds = await _queryKana(
connection,
word,
pageSize: pageSize,
pageSize,
offset,
);
entryIds = (await connection.rawQuery(query, args))
.map((row) => ScoredEntryId(
row['entryId'] as int,
row['score'] as int,
))
.toList();
break;
case SearchMode.English:
entryIds = (await connection.rawQuery(
'''
SELECT DISTINCT
"${JMdictTableNames.sense}"."entryId"
FROM "${JMdictTableNames.senseGlossary}"
JOIN "${JMdictTableNames.sense}" USING ("senseId")
WHERE "${JMdictTableNames.senseGlossary}"."phrase" LIKE ?
LIMIT ?
OFFSET ?
'''
.trim(),
[
'%$word%',
pageSize,
offset,
],
))
.map((row) => ScoredEntryId(
row['entryId'] as int,
0,
))
.toList();
entryIds = await _queryEnglish(
connection,
word,
pageSize,
offset,
);
break;
case SearchMode.MixedKana:
@@ -187,41 +290,24 @@ Future<int?> fetchEntryIdCount(
switch (searchMode) {
case SearchMode.Kanji:
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.kanjiElement,
entryIdCount = await _queryKanjiCount(
connection,
word,
pageSize: 1,
countOnly: true,
);
entryIdCount = (await connection.rawQuery(query, args))
.firstOrNull?['count'] as int?;
break;
case SearchMode.Kana:
final (query, args) = _kanjiReadingTemplate(
JMdictTableNames.readingElement,
entryIdCount = await _queryKanaCount(
connection,
word,
pageSize: 1,
countOnly: true,
);
entryIdCount = (await connection.rawQuery(query, args))
.firstOrNull?['count'] as int?;
break;
case SearchMode.English:
entryIdCount = (await connection.rawQuery(
'''
SELECT COUNT(DISTINCT "${JMdictTableNames.sense}"."entryId") AS "count"
FROM "${JMdictTableNames.senseGlossary}"
JOIN "${JMdictTableNames.sense}" USING ("senseId")
WHERE "${JMdictTableNames.senseGlossary}"."phrase" LIKE ?
'''
.trim(),
[
'%$word%',
],
))
.firstOrNull?['count'] as int?;
entryIdCount = await _queryEnglishCount(
connection,
word,
);
break;
case SearchMode.MixedKana:

View File

@@ -73,3 +73,12 @@ WHERE "JMdict_EntryScore"."common" = 1;
CREATE VIEW "RADKFILE_Radicals" AS
SELECT DISTINCT "radical" FROM "RADKFILE";
CREATE VIEW "JMdict_CombinedEntryScore"
AS
SELECT
"JMdict_EntryScore"."entryId",
MAX("JMdict_EntryScore"."score") AS "score",
MAX("JMdict_EntryScore"."common") AS "common"
FROM "JMdict_EntryScore"
GROUP BY "JMdict_EntryScore"."entryId";