diff options
Diffstat (limited to 'base/src/database.rs')
-rw-r--r-- | base/src/database.rs | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/base/src/database.rs b/base/src/database.rs index 28cafaa..3c8bef4 100644 --- a/base/src/database.rs +++ b/base/src/database.rs @@ -19,9 +19,10 @@ use std::{ use tantivy::{ collector::{Count, TopDocs}, directory::MmapDirectory, + doc, query::QueryParser, schema::{Field, Schema, Value, FAST, INDEXED, STORED, STRING, TEXT}, - DateOptions, Index, IndexReader, IndexWriter, ReloadPolicy, TantivyDocument, + DateOptions, DateTime, Index, IndexReader, IndexWriter, ReloadPolicy, TantivyDocument, }; const T_USER: TableDefinition<&str, Ser<User>> = TableDefinition::new("user"); @@ -38,7 +39,7 @@ const T_IMPORT_FILE_MTIME: TableDefinition<&[u8], u64> = TableDefinition::new("i #[derive(Clone)] pub struct Database { inner: Arc<redb::Database>, - node_index: Arc<NodeIndex>, + text_search: Arc<NodeTextSearchIndex>, } impl Database { @@ -47,10 +48,10 @@ impl Database { info!("opening kv store..."); let db = redb::Database::create(path.join("data")).context("opening kv store")?; info!("opening node index..."); - let ft_node = NodeIndex::new(path).context("in node index")?; + let ft_node = NodeTextSearchIndex::new(path).context("in node index")?; let r = Self { inner: db.into(), - node_index: ft_node.into(), + text_search: ft_node.into(), }; { @@ -287,13 +288,13 @@ impl Database { } pub fn search(&self, query: &str, page: usize) -> Result<(usize, Vec<NodeID>)> { let query = QueryParser::for_index( - &self.node_index.index, - vec![self.node_index.title, self.node_index.description], + &self.text_search.index, + vec![self.text_search.title, self.text_search.description], ) .parse_query(query) .context("parsing query")?; - let searcher = self.node_index.reader.searcher(); + let searcher = self.text_search.reader.searcher(); let sres = searcher.search(&query, &TopDocs::with_limit(32).and_offset(page * 32))?; let scount = searcher.search(&query, &Count)?; @@ -301,7 +302,7 @@ impl Database { for (_, daddr) in sres { let doc: TantivyDocument = searcher.doc(daddr)?; let id = doc - .get_first(self.node_index.id) + .get_first(self.text_search.id) .unwrap() .as_bytes() .unwrap(); @@ -310,6 +311,30 @@ impl Database { } Ok((scount, results)) } + + pub fn search_create_index(&self) -> Result<()> { + let mut w = self.text_search.writer.write().unwrap(); + w.delete_all_documents()?; + + let txn = self.inner.begin_read()?; + let nodes = txn.open_table(T_NODE)?; + for node in nodes.iter()? { + let (x, y) = node?; + let (id, node) = (x.value().to_owned(), y.value().0); + + w.add_document(doc!( + self.text_search.id => id.to_vec(), + self.text_search.title => node.title.unwrap_or_default(), + self.text_search.description => node.description.unwrap_or_default(), + self.text_search.releasedate => DateTime::from_timestamp_millis(node.release_date.unwrap_or_default()), + self.text_search.f_index => node.index.unwrap_or_default() as u64, + ))?; + } + + w.commit()?; + Ok(()) + } + pub fn create_admin_user(&self, username: &str, password_hash: Vec<u8>) -> Result<()> { let txn = self.inner.begin_write().unwrap(); let mut users = txn.open_table(T_USER).unwrap(); @@ -355,7 +380,7 @@ impl Database { } } -pub struct NodeIndex { +pub struct NodeTextSearchIndex { pub schema: Schema, pub reader: IndexReader, pub writer: RwLock<IndexWriter>, @@ -367,7 +392,7 @@ pub struct NodeIndex { pub parent: Field, pub f_index: Field, } -impl NodeIndex { +impl NodeTextSearchIndex { fn new(path: &Path) -> anyhow::Result<Self> { let mut schema = Schema::builder(); let id = schema.add_text_field("id", TEXT | STORED | FAST); |