更新谚语搜索,调整搜索函数

This commit is contained in:
Miyamizu-MitsuhaSang 2025-11-03 00:12:37 +08:00
parent b16917215a
commit fe6c84e310
5 changed files with 48 additions and 32 deletions

View File

@ -334,16 +334,19 @@ Authorization: Bearer <your_jwt_token>
#### 2.2 法语谚语详情 #### 2.2 法语谚语详情
- **接口**: `POST /search/proverb` - **接口**: `POST /search/proverb`
- **描述**: 通过谚语ID获取法语谚语原文与中文解释 - **描述**: 根据谚语ID返回法语谚语全文与中文释义
- **需要认证**: 是 - **需要认证**: 是
- **查询参数**: - **请求类型**: `application/x-www-form-urlencoded`
- `proverb_id`: 谚语ID (integer) - **表单字段**:
- `proverb_id`: 谚语ID (integer必填)
- **响应**: - **响应**:
```json ```json
{ {
"proverb_text": "Petit à petit, l'oiseau fait son nid.", "result": {
"chi_exp": "循序渐进才能取得成功。" "proverb_text": "Petit à petit, l'oiseau fait son nid.",
"chi_exp": "循序渐进才能取得成功。"
}
} }
``` ```
@ -380,14 +383,13 @@ Authorization: Bearer <your_jwt_token>
#### 2.4 谚语联想建议 #### 2.4 谚语联想建议
- **接口**: `POST /search/proverb/list` - **接口**: `POST /search/proverb/list`
- **描述**: 按输入内容(自动识别法语或中文)返回谚语候选列表 - **描述**: 按输入内容返回谚语候选列表,后端会自动检测输入语言(中文/日文假名/拉丁字母),无法识别时退回法语字段搜索
- **需要认证**: 是 - **需要认证**: 是
- **请求体**: - **请求体**:
```json ```json
{ {
"query": "慢", "query": "慢"
"language": "fr"
} }
``` ```
@ -405,6 +407,9 @@ Authorization: Bearer <your_jwt_token>
} }
``` ```
- **状态码**:
- `200`: 查询成功
--- ---
### 3. 翻译模块 (`/translate`) ### 3. 翻译模块 (`/translate`)
@ -437,6 +442,7 @@ Authorization: Bearer <your_jwt_token>
} }
``` ```
- **限制**: 依赖 Redis 计数器做限流,同一用户每秒最多 2 次请求(超出返回 `429`
- **状态码**: - **状态码**:
- `200`: 翻译成功 - `200`: 翻译成功
- `401`: 未授权 - `401`: 未授权
@ -452,7 +458,7 @@ Authorization: Bearer <your_jwt_token>
- `from_lang`: 源语言,默认为 `auto` - `from_lang`: 源语言,默认为 `auto`
- `to_lang`: 目标语言,默认为 `zh` - `to_lang`: 目标语言,默认为 `zh`
- **限制**: 每秒最多2次请求 - **限制**: 与标准翻译接口共享限流计数,同一用户每秒最多2次请求
- **状态码**: - **状态码**:
- `200`: 翻译成功 - `200`: 翻译成功
- `429`: 请求频率过高 - `429`: 请求频率过高
@ -770,7 +776,8 @@ Authorization: Bearer <your_jwt_token>
- **需要认证**: 是 - **需要认证**: 是
- **查询参数**: - **查询参数**:
- `count`: 抽题数量 (integer默认 `20`) - `count`: 抽题数量 (integer默认 `20`)
- `lang`: 语种代码,支持 `fr-FR`(法语)、`ja-JP`(日语),默认 `fr-FR` - **表单字段**:
- `lang`: 语种代码(`fr-FR` 或 `ja-JP`,默认 `fr-FR`。由于实现方式FastAPI 将其视为 form-data 字段GET 请求需通过 form 提交或在调试文档中直接填写。
- **响应**: - **响应**:
```json ```json

View File

@ -1,6 +1,6 @@
from typing import Literal, List from typing import Literal, List
from fastapi import APIRouter, Depends, HTTPException, Request from fastapi import APIRouter, Depends, HTTPException, Request, Form
from app.api.search_dict import service from app.api.search_dict import service
from app.api.search_dict.search_schemas import SearchRequest, WordSearchResponse, SearchItemFr, SearchItemJp, \ from app.api.search_dict.search_schemas import SearchRequest, WordSearchResponse, SearchItemFr, SearchItemJp, \
@ -167,10 +167,17 @@ async def search_word_list(query_word: SearchRequest, user=Depends(get_current_u
@dict_search.post("/search/proverb/list") @dict_search.post("/search/proverb/list")
async def search_proverb_list(query_word: ProverbSearchRequest): async def search_proverb_list(query_word: ProverbSearchRequest):
lang = service.detect_language(text=query_word.query) lang = service.detect_language(text=query_word.query)
query = normalize_text(query_word.query) if lang == "fr" else query_word.query
suggest_proverbs = await service.suggest_proverb( suggest_proverbs = await service.suggest_proverb(
query=query_word.query, query=query_word.query,
lang=lang, lang=lang,
model=ProverbFr, model=ProverbFr,
search_field="search_text",
) )
# TODO 使用法语词典时是否存在用英语输入的情况 # TODO 使用法语词典时是否存在用英语输入的情况
return {"list": suggest_proverbs} return {"list": suggest_proverbs}
@dict_search.post("/search/proverb")
async def search_proverb(proverb_id:int = Form(...), user=Depends(get_current_user)):
result = await service.accurate_proverb(proverb_id=proverb_id)
return {"result": result}

View File

@ -39,12 +39,13 @@ async def accurate_proverb(proverb_id: int) -> ProverbSearchResponse:
async def suggest_proverb( async def suggest_proverb(
query: str, query: str,
lang: Literal["fr", "zh", "jp"], lang: Literal["fr", "zh", "jp"],
model: Type[Model], model: Type[Model],
proverb_field: str = "text", search_field: str = "search_text",
chi_exp_field: str = "chi_exp", target_field: str = "text",
limit: int = 10, chi_exp_field: str = "chi_exp",
limit: int = 10,
) -> List[Dict[str, str]]: ) -> List[Dict[str, str]]:
""" """
通用搜索建议函数用于多语言谚语表 通用搜索建议函数用于多语言谚语表
@ -71,15 +72,15 @@ async def suggest_proverb(
startswith_field = f"{chi_exp_field}__istartswith" startswith_field = f"{chi_exp_field}__istartswith"
contains_field = f"{chi_exp_field}__icontains" contains_field = f"{chi_exp_field}__icontains"
else: else:
startswith_field = f"{proverb_field}__istartswith" startswith_field = f"{search_field}__istartswith"
contains_field = f"{proverb_field}__icontains" contains_field = f"{search_field}__icontains"
# ✅ 1. 开头匹配 # ✅ 1. 开头匹配
start_matches = await ( start_matches = await (
model.filter(**{startswith_field: keyword}) model.filter(**{startswith_field: keyword})
.order_by("-freq") .order_by("-freq")
.limit(limit) .limit(limit)
.values("id", proverb_field, chi_exp_field) .values("id", target_field, search_field, chi_exp_field)
) )
# ✅ 2. 包含匹配(非开头) # ✅ 2. 包含匹配(非开头)
@ -89,7 +90,7 @@ async def suggest_proverb(
) )
.order_by("-freq") .order_by("-freq")
.limit(limit) .limit(limit)
.values("id", proverb_field, chi_exp_field) .values("id", target_field, search_field, chi_exp_field)
) )
# ✅ 3. 合并去重并保持顺序 # ✅ 3. 合并去重并保持顺序
@ -100,7 +101,8 @@ async def suggest_proverb(
seen_ids.add(row["id"]) seen_ids.add(row["id"])
results.append({ results.append({
"id": row["id"], "id": row["id"],
"proverb": row[proverb_field], "proverb": row[target_field],
"search_text": row[search_field],
"chi_exp": row[chi_exp_field] "chi_exp": row[chi_exp_field]
}) })
@ -225,4 +227,4 @@ async def __main():
if __name__ == '__main__': if __name__ == '__main__':
# asyncio.run(__main()) # asyncio.run(__main())
print(detect_language(text="ahsjdasd")) print(detect_language(text="ahsjdasd"))

View File

@ -48,6 +48,7 @@ class ProverbFr(Model):
text = fields.TextField(description="法语谚语及常用表达") text = fields.TextField(description="法语谚语及常用表达")
chi_exp = fields.TextField(description="中文释义") chi_exp = fields.TextField(description="中文释义")
freq = fields.IntField(default=0) freq = fields.IntField(default=0)
search_text = fields.TextField()
created_at = fields.DatetimeField(auto_now_add=True) created_at = fields.DatetimeField(auto_now_add=True)
class Meta: class Meta:

View File

@ -2,7 +2,7 @@ import asyncio
from pathlib import Path from pathlib import Path
import pandas as pd import pandas as pd
from tortoise import Tortoise, connections from tortoise import Tortoise
from tortoise.exceptions import MultipleObjectsReturned from tortoise.exceptions import MultipleObjectsReturned
from app.models.fr import DefinitionFr, WordlistFr from app.models.fr import DefinitionFr, WordlistFr
@ -101,14 +101,13 @@ async def varification_eg():
async def main(): async def main():
await Tortoise.init(config=TORTOISE_ORM) await Tortoise.init(config=TORTOISE_ORM)
await DefinitionFr.all().delete() # TRUNCATE TABLE definitions_fr; # await DefinitionFr.all().delete() # TRUNCATE TABLE definitions_fr;
conn = connections.get("default") # conn = connections.get("default")
await conn.execute_script(""" # await conn.execute_script("""
ALTER TABLE definitions_fr AUTO_INCREMENT = 1; # ALTER TABLE definitions_fr AUTO_INCREMENT = 1;
""") # """)
await import_def_fr() # await import_def_fr()
# await import_wordlist_fr() # # await import_wordlist_fr()
if __name__ == "__main__": if __name__ == "__main__":
asyncio.run(main()) asyncio.run(main())