自定义搜索函数
搜索是 Sonolus 服务器的一个核心功能。接下来,本页面将向您介绍如何自定义搜索函数。
Sonolus 默认会自带一个 quick
类型的快速搜索,其它的就需要您自行配置。
配置语法
Search 类的结构介绍在这里(官方叫 ServerOption
)。
class SearchConfig {
public:
string title; // 搜索标题
string icon; // 搜索图标
string type; // 搜索类型
vector<Search> options; // 搜索选项
string filter; // 筛选时 SQL 代码
string order; // 排序时 SQL 代码
};
title
可以使用 Sonolus 的文本内容,详见 Sonolus/sonolus-core。icon
只能使用 Sonolus 支持的图标代号,详见 Sonolus/sonolus-core。filter
和order
的值为 SQL 表达式,可以使用{{xxx}}
结构来代表查询参数。type
的值不可以为quick
,否则会与 Sonolus 的默认搜索冲突。- 对于
mutli
类型的 Search 类,有以下特殊属性,具体使用方法可以参考level_config.json
中的Advanced Search
:
class SearchMultiOptionVariable {
public:
string name = ""; // 自定义的变量名称
string expr = ""; // 自定义的 SQL 变量表达式,只能使用该选项的用户输入参数
string connector = ""; // 每两项之间的逻辑运算符
string default = ""; // 用户没有选择时的默认值
};
class SearchMultiOption {
public:
// ...
vector<SearchMultiOptionVariable> variables; // 自定义变量
}
配置示例
快速搜索
本配置复刻了 Sonolus 的关卡快速搜索功能,实际无法运用到 Sonolus 中,会导致类型冲突。
{
"title": "#SEARCH",
"icon": "search",
"type": "quick",
"options": [
{
"query": "keyword",
"name": "#KEYWORD",
"type": "text",
"placeholder": "#KEYWORD_PLACEHOLDER",
"limit": 0
}
],
"filter": "title LIKE \"%{{keyword}}%\"",
"order": "id DESC"
}
如果你访问 /sonolus/levels/list?type=quick&keyword=Test
或 /levels/list?type=quick&keyword=Test
,生成的 SQL 如下:
SELECT * FROM Level
WHERE (title LIKE "%Test%")
ORDER BY id DESC
随机排序
本配置实现了随机排列 Sonolus 的关卡,仅供参考。
{
"title": "#RANDOM",
"icon": "search",
"type": "random",
"options": [
{
"query": "random",
"name": "#RANDOM",
"type": "toggle",
"def": 0
}
],
"filter": "",
"order": "CASE {{random}} WHEN 0 THEN id WHEN 1 THEN RANDOM() END DESC"
}
如果你访问 /sonolus/levels/list?type=random&random=0
或 /levels/list?type=random&random=0
,生成的 SQL 如下:
SELECT * FROM Level
WHERE ()
ORDER BY
CASE 0
WHEN 0 THEN id
WHEN 1 THEN RANDOM()
END DESC
如果你访问 /sonolus/levels/list?type=random&random=1
或 /levels/list?type=random&random=1
,生成的 SQL 如下:
SELECT * FROM Level
WHERE ()
ORDER BY
CASE 1
WHEN 0 THEN id
WHEN 1 THEN RANDOM()
END DESC
难度选择
本配置实现了难度的多项选择框,仅供参考。
{
"title": "#DIFFICULTY",
"icon": "search",
"type": "difficulty",
"options": [
{
"query": "difficulty",
"name": "#DIFFICULTY",
"type": "multi",
"def": [ 1, 1, 1, 1, 1 ],
"values": [ "EZ", "HD", "IN", "AT", "SP" ],
"variables": [
{
"name": "difficulty_or",
"expr": "tags LIKE \"%({{difficulty}},)%\"",
"connector": "OR",
"default": "0"
}, {
"name": "difficulty_and",
"expr": "tags LIKE \"%({{difficulty}},)%\"",
"connector": "AND",
"default": "1"
}
]
}
],
"filter": "{{difficulty_or}}",
"order": "id DESC"
}
如果你访问 /sonolus/levels/list?type=difficulty&difficulty=00000
或 /levels/list?type=difficulty&difficulty=00000
,生成的 SQL 如下:
SELECT * FROM Level
WHERE (0)
ORDER BY id DESC
如果你访问 /sonolus/levels/list?type=difficulty&difficulty=10001
或 /levels/list?type=difficulty&difficulty=10001
,生成的 SQL 如下:
SELECT * FROM Level
WHERE (tags LIKE "%(EZ,)%" OR tags LIKE "%(SP,)%")
ORDER BY id DESC
如果你访问 /sonolus/levels/list?type=difficulty
或 /levels/list?type=difficulty
,生成的 SQL 如下:
SELECT * FROM Level
WHERE (tags LIKE "%(EZ,)%" OR tags LIKE "%(HD,)%" OR tags LIKE "%(IN,)%" OR tags LIKE "%(AT,)%" OR tags LIKE "%(SP,)%")
ORDER BY id DESC