aboutsummaryrefslogtreecommitdiff
path: root/database/src/search.rs
blob: a7c074f6a7c9cbbef9ef670080972f7c651b44e7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/*
    This file is part of jellything (https://codeberg.org/metamuffin/jellything)
    which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
    Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use anyhow::Context;
use std::{fs::create_dir_all, path::Path, sync::RwLock};
use tantivy::{
    DateOptions, Index, IndexReader, IndexWriter, ReloadPolicy,
    directory::MmapDirectory,
    schema::{FAST, Field, INDEXED, STORED, STRING, Schema, TEXT},
};

pub struct NodeTextSearchIndex {
    pub schema: Schema,
    pub reader: IndexReader,
    pub writer: RwLock<IndexWriter>,
    pub index: Index,
    pub id: Field,
    pub title: Field,
    pub releasedate: Field,
    pub description: Field,
    pub parent: Field,
    pub f_index: Field,
}
impl NodeTextSearchIndex {
    pub(crate) fn new(path: &Path) -> anyhow::Result<Self> {
        let mut schema = Schema::builder();
        let id = schema.add_text_field("id", TEXT | STORED | FAST);
        let title = schema.add_text_field("title", TEXT);
        let description = schema.add_text_field("description", TEXT);
        let parent = schema.add_text_field("parent", STRING | FAST);
        let f_index = schema.add_u64_field("index", FAST);
        let releasedate = schema.add_date_field(
            "releasedate",
            DateOptions::from(INDEXED)
                .set_fast()
                .set_precision(tantivy::DateTimePrecision::Seconds),
        );
        let schema = schema.build();
        create_dir_all(path.join("node_index"))?;
        let directory =
            MmapDirectory::open(path.join("node_index")).context("opening index directory")?;
        let index = Index::open_or_create(directory, schema.clone()).context("creating index")?;
        let reader = index
            .reader_builder()
            .reload_policy(ReloadPolicy::OnCommitWithDelay)
            .try_into()
            .context("creating reader")?;
        let writer = index.writer(30_000_000).context("creating writer")?;
        Ok(Self {
            index,
            writer: writer.into(),
            reader,
            schema,
            parent,
            f_index,
            releasedate,
            id,
            description,
            title,
        })
    }
}