add limit & offset to the query

This commit is contained in:
Nikita Galaiko 2023-03-06 10:57:09 +01:00
parent cfd151fcb9
commit c6c3c3feb5
5 changed files with 73 additions and 22 deletions

View File

@ -142,15 +142,24 @@ fn search(
handle: tauri::AppHandle, handle: tauri::AppHandle,
project_id: &str, project_id: &str,
query: &str, query: &str,
limit: Option<usize>,
offset: Option<usize>,
) -> Result<Vec<search::SearchResult>, Error> { ) -> Result<Vec<search::SearchResult>, Error> {
let app_state = handle.state::<App>(); let app_state = handle.state::<App>();
let query = search::SearchQuery {
project_id: project_id.to_string(),
q: query.to_string(),
limit: limit.unwrap_or(100),
offset,
};
let deltas = app_state let deltas = app_state
.deltas_searcher .deltas_searcher
.lock() .lock()
.unwrap() .unwrap()
.search(project_id, query) .search(&query)
.with_context(|| format!("Failed to search for {}", query))?; .with_context(|| format!("Failed to search for {:?}", query))?;
Ok(deltas) Ok(deltas)
} }

View File

@ -81,8 +81,8 @@ impl Deltas {
}) })
} }
pub fn search(&self, project_id: &str, query: &str) -> Result<Vec<SearchResult>> { pub fn search(&self, query: &SearchQuery) -> Result<Vec<SearchResult>> {
search(&self.index, &self.reader, project_id, query) search(&self.index, &self.reader, query)
} }
pub fn reindex_project( pub fn reindex_project(
@ -262,11 +262,18 @@ fn index(
Ok(()) Ok(())
} }
#[derive(Debug, Default)]
pub struct SearchQuery {
pub q: String,
pub project_id: String,
pub limit: usize,
pub offset: Option<usize>,
}
pub fn search( pub fn search(
index: &tantivy::Index, index: &tantivy::Index,
reader: &tantivy::IndexReader, reader: &tantivy::IndexReader,
project_id: &str, q: &SearchQuery,
q: &str,
) -> Result<Vec<SearchResult>> { ) -> Result<Vec<SearchResult>> {
let query = &tantivy::query::QueryParser::for_index( let query = &tantivy::query::QueryParser::for_index(
index, index,
@ -278,7 +285,7 @@ pub fn search(
.parse_query( .parse_query(
format!( format!(
"version:\"{}\" AND project_id:\"{}\" AND ({})", "version:\"{}\" AND project_id:\"{}\" AND ({})",
CURRENT_VERSION, project_id, q CURRENT_VERSION, q.project_id, q.q,
) )
.as_str(), .as_str(),
)?; )?;
@ -288,7 +295,8 @@ pub fn search(
let top_docs = searcher.search( let top_docs = searcher.search(
query, query,
&collector::TopDocs::with_limit(10) &collector::TopDocs::with_limit(q.limit)
.and_offset(q.offset.unwrap_or(0))
.order_by_u64_field(index.schema().get_field("timestamp_ms").unwrap()), .order_by_u64_field(index.schema().get_field("timestamp_ms").unwrap()),
)?; )?;

View File

@ -55,7 +55,12 @@ fn test_sorted_by_timestamp() {
let write_result = searcher.index_session(&repo, &project, &session); let write_result = searcher.index_session(&repo, &project, &session);
assert!(write_result.is_ok()); assert!(write_result.is_ok());
let search_result = searcher.search(&project.id, "hello world"); let search_result = searcher.search(&super::SearchQuery {
project_id: project.id,
q: "hello world".to_string(),
limit: 10,
..Default::default()
});
assert!(search_result.is_ok()); assert!(search_result.is_ok());
let search_result = search_result.unwrap(); let search_result = search_result.unwrap();
assert_eq!(search_result.len(), 2); assert_eq!(search_result.len(), 2);
@ -92,7 +97,12 @@ fn test_simple() {
let write_result = searcher.index_session(&repo, &project, &session); let write_result = searcher.index_session(&repo, &project, &session);
assert!(write_result.is_ok()); assert!(write_result.is_ok());
let search_result1 = searcher.search(&project.id, "hello"); let search_result1 = searcher.search(&super::SearchQuery {
project_id: project.id.clone(),
q: "hello".to_string(),
limit: 10,
..Default::default()
});
assert!(search_result1.is_ok()); assert!(search_result1.is_ok());
let search_result1 = search_result1.unwrap(); let search_result1 = search_result1.unwrap();
assert_eq!(search_result1.len(), 1); assert_eq!(search_result1.len(), 1);
@ -101,7 +111,12 @@ fn test_simple() {
assert_eq!(search_result1[0].file_path, "test.txt"); assert_eq!(search_result1[0].file_path, "test.txt");
assert_eq!(search_result1[0].index, 0); assert_eq!(search_result1[0].index, 0);
let search_result2 = searcher.search(&project.id, "world"); let search_result2 = searcher.search(&super::SearchQuery {
project_id: project.id.clone(),
q: "world".to_string(),
limit: 10,
..Default::default()
});
assert!(search_result2.is_ok()); assert!(search_result2.is_ok());
let search_result2 = search_result2.unwrap(); let search_result2 = search_result2.unwrap();
assert_eq!(search_result2.len(), 1); assert_eq!(search_result2.len(), 1);
@ -110,7 +125,12 @@ fn test_simple() {
assert_eq!(search_result2[0].file_path, "test.txt"); assert_eq!(search_result2[0].file_path, "test.txt");
assert_eq!(search_result2[0].index, 1); assert_eq!(search_result2[0].index, 1);
let search_result3 = searcher.search(&project.id, "hello world"); let search_result3 = searcher.search(&super::SearchQuery {
project_id: project.id.clone(),
q: "hello world".to_string(),
limit: 10,
..Default::default()
});
println!("{:?}", search_result3); println!("{:?}", search_result3);
assert!(search_result3.is_ok()); assert!(search_result3.is_ok());
let search_result3 = search_result3.unwrap(); let search_result3 = search_result3.unwrap();
@ -122,7 +142,12 @@ fn test_simple() {
assert_eq!(search_result3[1].project_id, project.id); assert_eq!(search_result3[1].project_id, project.id);
assert_eq!(search_result3[1].file_path, "test.txt"); assert_eq!(search_result3[1].file_path, "test.txt");
let search_by_filename_result = searcher.search(&project.id, "test.txt"); let search_by_filename_result = searcher.search(&super::SearchQuery {
project_id: project.id.clone(),
q: "test.txt".to_string(),
limit: 10,
..Default::default()
});
assert!(search_by_filename_result.is_ok()); assert!(search_by_filename_result.is_ok());
let search_by_filename_result = search_by_filename_result.unwrap(); let search_by_filename_result = search_by_filename_result.unwrap();
assert_eq!(search_by_filename_result.len(), 2); assert_eq!(search_by_filename_result.len(), 2);
@ -130,7 +155,12 @@ fn test_simple() {
assert_eq!(search_by_filename_result[0].project_id, project.id); assert_eq!(search_by_filename_result[0].project_id, project.id);
assert_eq!(search_by_filename_result[0].file_path, "test.txt"); assert_eq!(search_by_filename_result[0].file_path, "test.txt");
let not_found_result = searcher.search("404", "hello world"); let not_found_result = searcher.search(&super::SearchQuery {
project_id: "not found".to_string(),
q: "test.txt".to_string(),
limit: 10,
..Default::default()
});
assert!(not_found_result.is_ok()); assert!(not_found_result.is_ok());
let not_found_result = not_found_result.unwrap(); let not_found_result = not_found_result.unwrap();
assert_eq!(not_found_result.len(), 0); assert_eq!(not_found_result.len(), 0);

View File

@ -1,6 +1,6 @@
mod deltas; mod deltas;
pub use deltas::{Deltas, SearchResult}; pub use deltas::{Deltas, SearchResult, SearchQuery};
#[cfg(test)] #[cfg(test)]
mod deltas_test; mod deltas_test;

View File

@ -8,5 +8,9 @@ export type SearchResult = {
index: number; index: number;
}; };
export const search = (params: { projectId: string; query: string }) => export const search = (params: {
invoke<SearchResult[]>('search', params); projectId: string;
query: string;
limit?: number;
offset?: number;
}) => invoke<SearchResult[]>('search', params);