Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit14c7a05

Browse files
committed
Search refinements (#1337)
1 parent00d39d4 commit14c7a05

File tree

3 files changed

+69
-18
lines changed

3 files changed

+69
-18
lines changed

‎pgml-dashboard/src/api/cms.rs‎

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
guards::Cluster,
1717
responses::{Response,ResponseOk,Template},
1818
templates::docs::*,
19-
utils::config,
19+
utils::{config, markdown::SearchResult},
2020
};
2121
use serde::{Deserialize,Serialize};
2222
use std::fmt;
@@ -626,6 +626,40 @@ impl Collection {
626626
#[get("/search?<query>", rank =20)]
627627
asyncfnsearch(query:&str,site_search:&State<crate::utils::markdown::SiteSearch>) ->ResponseOk{
628628
let results = site_search.search(query,None).await.expect("Error performing search");
629+
630+
let results:Vec<SearchResult> = results
631+
.into_iter()
632+
.map(|document|{
633+
let snippet =ifletSome(description) = document.description{
634+
description
635+
}else{
636+
let author = document.author.unwrap_or_else(||String::from("xzxzxz"));
637+
// The heuristics used here are ok, not the best it will be better when we can just use the description field
638+
document
639+
.contents
640+
.lines()
641+
.find(|l| !l.is_empty() && !l.contains(&document.title) && !l.contains(&author) && l.len() >30)
642+
.unwrap_or("")
643+
.split(' ')
644+
.take(20)
645+
.collect::<Vec<&str>>()
646+
.join(" ")
647+
+"&nbsp;..."
648+
};
649+
let path = document
650+
.path
651+
.to_str()
652+
.unwrap_or_default()
653+
.replace(".md","")
654+
.replace(&config::static_dir().display().to_string(),"");
655+
SearchResult{
656+
title: document.title,
657+
path,
658+
snippet,
659+
}
660+
})
661+
.collect();
662+
629663
ResponseOk(
630664
Template(Search{
631665
query: query.to_string(),

‎pgml-dashboard/src/utils/markdown.rs‎

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
usecrate::api::cms::{DocType,Document};
22
usecrate::{templates::docs::TocLink, utils::config};
33
use anyhow::Context;
4+
use comrak::{format_html_with_plugins, parse_document,ComrakPlugins};
45
use std::cell::RefCell;
56
use std::collections::HashMap;
67
use std::path::PathBuf;
@@ -21,6 +22,9 @@ use std::fmt;
2122
use std::sync::Mutex;
2223
use url::Url;
2324

25+
// Excluded paths in the pgml-cms directory
26+
constEXCLUDED_DOCUMENT_PATHS:[&str;1] =["blog/README.md"];
27+
2428
pubstructMarkdownHeadings{
2529
header_map:Arc<Mutex<HashMap<String,usize>>>,
2630
}
@@ -1291,7 +1295,7 @@ impl SiteSearch {
12911295
.collect()
12921296
}
12931297

1294-
pubasyncfnsearch(&self,query:&str,doc_type:Option<DocType>) -> anyhow::Result<Vec<SearchResult>>{
1298+
pubasyncfnsearch(&self,query:&str,doc_type:Option<DocType>) -> anyhow::Result<Vec<Document>>{
12951299
letmut search = serde_json::json!({
12961300
"query":{
12971301
// "full_text_search": {
@@ -1323,29 +1327,19 @@ impl SiteSearch {
13231327
"limit":10
13241328
});
13251329
ifletSome(doc_type) = doc_type{
1326-
search["query"]["filter"] = serde_json::json!({
1327-
"doc_type":{
1328-
"$eq": doc_type
1329-
}
1330+
search["query"]["filter"]["doc_type"] = serde_json::json!({
1331+
"$eq": doc_type
13301332
});
13311333
}
13321334
let results =self.collection.search_local(search.into(),&self.pipeline).await?;
13331335

13341336
results["results"]
13351337
.as_array()
13361338
.context("Error getting results from search")?
1337-
.into_iter()
1339+
.iter()
13381340
.map(|r|{
1339-
letSearchResultWithoutSnippet{ title, contents, path} =
1340-
serde_json::from_value(r["document"].clone())?;
1341-
let path = path
1342-
.replace(".md","")
1343-
.replace(&config::static_dir().display().to_string(),"");
1344-
Ok(SearchResult{
1345-
title,
1346-
path,
1347-
snippet: contents.split(' ').take(20).collect::<Vec<&str>>().join(" ") +"&nbsp;...",
1348-
})
1341+
let document:Document = serde_json::from_value(r["document"].clone())?;
1342+
Ok(document)
13491343
})
13501344
.collect()
13511345
}
@@ -1358,6 +1352,24 @@ impl SiteSearch {
13581352
.map(|path|asyncmove{Document::from_path(&path).await}),
13591353
)
13601354
.await?;
1355+
// Filter out documents who only have 1 line (this is usually just an empty document with the title as the first line)
1356+
// and documents that are in our excluded paths list
1357+
let documents:Vec<Document> = documents
1358+
.into_iter()
1359+
.filter(|f|{
1360+
!EXCLUDED_DOCUMENT_PATHS
1361+
.iter()
1362+
.any(|p| f.path == config::cms_dir().join(p))
1363+
&& !f
1364+
.contents
1365+
.lines()
1366+
.skip(1)
1367+
.collect::<Vec<&str>>()
1368+
.join("")
1369+
.trim()
1370+
.is_empty()
1371+
})
1372+
.collect();
13611373
let documents:Vec<pgml::types::Json> = documents
13621374
.into_iter()
13631375
.map(|d|{

‎pgml-dashboard/static/js/search.js‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,16 @@ export default class extends Controller {
1515
this.target.addEventListener('shown.bs.modal',this.focusSearchInput)
1616
this.target.addEventListener('hidden.bs.modal',this.updateSearch)
1717
this.searchInput.addEventListener('input',(e)=>this.search(e))
18+
19+
this.timer;
1820
}
1921

2022
search(e){
23+
clearTimeout(this.timer);
2124
constquery=e.currentTarget.value
22-
this.searchFrame.src=`/search?query=${query}`
25+
this.timer=setTimeout(()=>{
26+
this.searchFrame.src=`/search?query=${query}`
27+
},250);
2328
}
2429

2530
focusSearchInput=(e)=>{

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp