Refactor search
parent
88381113cd
commit
3ccbb09c26
|
@ -60,6 +60,14 @@ struct SearchQuery {
|
|||
language: String,
|
||||
include: String,
|
||||
ignore: Option<Vec<String>>,
|
||||
option: SearchType,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
enum SearchType {
|
||||
Fuzzy,
|
||||
Regex,
|
||||
Sql,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -71,6 +79,48 @@ struct SearchResult {
|
|||
last_updated: DateTime<Utc>,
|
||||
}
|
||||
|
||||
async fn fuzzy_search(
|
||||
title: &str,
|
||||
summary: &str,
|
||||
url: &str,
|
||||
last_updated: i64,
|
||||
size: i64,
|
||||
query: &SearchQuery,
|
||||
) -> Option<(i64, SearchResult)> {
|
||||
let mut score = 0;
|
||||
let matcher = SkimMatcherV2::default();
|
||||
|
||||
let t_match = matcher.fuzzy_match(title, &query.include);
|
||||
let s_match = matcher.fuzzy_match(summary, &query.include);
|
||||
let u_match = matcher.fuzzy_match(url, &query.include);
|
||||
if t_match.is_some() {
|
||||
score += t_match.unwrap();
|
||||
}
|
||||
if s_match.is_some() {
|
||||
score += s_match.unwrap() / 2;
|
||||
}
|
||||
if u_match.is_some() {
|
||||
score += u_match.unwrap() / 2;
|
||||
}
|
||||
if score > 5 {
|
||||
let timestamp = DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp_opt(last_updated, 0).unwrap(),
|
||||
Utc,
|
||||
);
|
||||
return Some((
|
||||
score,
|
||||
SearchResult {
|
||||
url: Url::parse(url).unwrap(),
|
||||
size: size,
|
||||
title: title.to_string(),
|
||||
summary: summary.to_string(),
|
||||
last_updated: timestamp,
|
||||
},
|
||||
));
|
||||
}
|
||||
return None;
|
||||
}
|
||||
|
||||
async fn search(
|
||||
State(state): State<Arc<AppState>>,
|
||||
Json(query): Json<SearchQuery>,
|
||||
|
@ -90,38 +140,26 @@ async fn search(
|
|||
.unwrap();
|
||||
|
||||
let mut results = BTreeMap::new();
|
||||
let matcher = SkimMatcherV2::default();
|
||||
for res in list {
|
||||
let mut is_match = false;
|
||||
let mut score = 0;
|
||||
let t_match = matcher.fuzzy_match(&res.title, &query.include);
|
||||
let s_match = matcher.fuzzy_match(&res.summary, &query.include);
|
||||
let u_match = matcher.fuzzy_match(&res.url, &query.include);
|
||||
if t_match.is_some() {
|
||||
score += t_match.unwrap();
|
||||
}
|
||||
if s_match.is_some() {
|
||||
score += s_match.unwrap() / 2;
|
||||
}
|
||||
if u_match.is_some() {
|
||||
score += u_match.unwrap() / 2;
|
||||
}
|
||||
if score > 5 {
|
||||
let timestamp = DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp_opt(res.last_updated, 0).unwrap(),
|
||||
Utc,
|
||||
);
|
||||
results.insert(
|
||||
score,
|
||||
SearchResult {
|
||||
url: Url::parse(&res.url).unwrap(),
|
||||
size: res.size,
|
||||
title: res.title,
|
||||
summary: res.summary,
|
||||
last_updated: timestamp,
|
||||
},
|
||||
);
|
||||
}
|
||||
match query.option {
|
||||
SearchType::Fuzzy => {
|
||||
match fuzzy_search(
|
||||
&res.title,
|
||||
&res.summary,
|
||||
&res.url,
|
||||
res.last_updated,
|
||||
res.size,
|
||||
&query,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Some((s, r)) => results.insert(s, r),
|
||||
None => None,
|
||||
};
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
}
|
||||
return Json(results);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue