1use anyhow::Result;
2
3use crate::engine::EngineState;
4use crate::search;
5
6pub struct SearchParams<'a> {
8 pub query: &'a str,
10 pub type_filter: Option<&'a str>,
12 pub no_excerpt: bool,
14 pub top_k: Option<usize>,
16 pub include_sections: bool,
18 pub cross_wiki: bool,
20}
21
22pub fn search(
24 engine: &EngineState,
25 wiki_name: &str,
26 params: &SearchParams<'_>,
27) -> Result<search::SearchResult> {
28 let space = engine.space(wiki_name)?;
29 let resolved = space.resolved_config(&engine.config);
30
31 let opts = search::SearchOptions {
32 no_excerpt: params.no_excerpt,
33 include_sections: params.include_sections,
34 top_k: params
35 .top_k
36 .unwrap_or(resolved.defaults.search_top_k as usize),
37 r#type: params.type_filter.map(|s| s.to_string()),
38 facets_top_tags: resolved.defaults.facets_top_tags as usize,
39 search_config: resolved.search.clone(),
40 };
41
42 if params.cross_wiki {
43 let mut wikis = Vec::new();
44 for s in engine.spaces.values() {
45 let searcher = s.index_manager.searcher()?;
46 wikis.push((s.name.clone(), searcher, &s.index_schema));
47 }
48 return search::search_all(params.query, &opts, &wikis);
49 }
50
51 let searcher = space.index_manager.searcher()?;
52 search::search(
53 params.query,
54 &opts,
55 &searcher,
56 wiki_name,
57 &space.index_schema,
58 )
59}
60
61pub fn list(
63 engine: &EngineState,
64 wiki_name: &str,
65 type_filter: Option<&str>,
66 status: Option<&str>,
67 page: usize,
68 page_size: Option<usize>,
69) -> Result<search::PageList> {
70 let space = engine.space(wiki_name)?;
71 let resolved = space.resolved_config(&engine.config);
72
73 let opts = search::ListOptions {
74 r#type: type_filter.map(|s| s.to_string()),
75 status: status.map(|s| s.to_string()),
76 page,
77 page_size: page_size.unwrap_or(resolved.defaults.list_page_size as usize),
78 facets_top_tags: resolved.defaults.facets_top_tags as usize,
79 };
80 let searcher = space.index_manager.searcher()?;
81 search::list(&opts, &searcher, wiki_name, &space.index_schema)
82}