use opendal::{Operator, services::Memory};
use sqlx::PgPool;
use tantivy::{
DocAddress, Index, IndexSettings, ReloadPolicy, Score, TantivyDocument,
collector::TopDocs,
doc,
query::QueryParser,
schema::{STORED, SchemaBuilder, TEXT},
};
use tokio::task;
use uuid::Uuid;
use crate::RemoteDirectory;
#[tokio::test]
async fn basic() {
let service = Memory::default();
let operator = Operator::new(service)
.expect("failed to create operator")
.finish();
let index = Uuid::new_v4();
let pool = PgPool::connect("postgresql://postgres:postgres@localhost:15432/postgres")
.await
.expect("failed to connect to database");
let cleanup = sqlx::query!(
r#"
DELETE
FROM tantivy.metadata
WHERE index = $1
"#,
index,
);
cleanup
.execute(&pool)
.await
.expect("failed to clean up metadata");
let directory = RemoteDirectory::open(index, operator, pool)
.await
.expect("failed to open directory");
let mut schema = SchemaBuilder::new();
let title = schema.add_text_field("title", TEXT | STORED);
let body = schema.add_text_field("body", TEXT);
let schema = schema.build();
let settings = IndexSettings::default();
let init = task::spawn_blocking(move || {
let index = Index::create(directory, schema, settings).expect("failed to create index");
let writer = index
.writer(100_000_000)
.expect("failed to create index writer");
(index, writer)
});
let (index, mut writer) = init.await.expect("failed to initialize index and writer");
let index_ = index.clone();
let init = task::spawn_blocking(move || {
let reader = index_
.reader_builder()
.reload_policy(ReloadPolicy::Manual)
.try_into()
.expect("failed to create index reader");
reader
});
let reader = init.await.expect("failed to initialize reader");
let write = task::spawn_blocking(move || {
writer
.add_document(doc!(
title => "The Old Man and the Sea",
body => "He was an old man who fished alone in a skiff in \
the Gulf Stream and he had gone eighty-four days \
now without taking a fish."
))
.expect("failed to add document");
writer.commit().expect("failed to commit");
});
write.await.expect("failed to write");
let parser = QueryParser::for_index(&index, vec![title, body]);
let query = parser
.parse_query("sea whale")
.expect("failed to parse query");
let reader_ = reader.clone();
let query_ = query.box_clone();
let search = task::spawn_blocking(move || {
reader_
.searcher()
.search(&query_, &TopDocs::with_limit(10))
.expect("failed to search")
});
let top_docs: Vec<(Score, DocAddress)> = search.await.expect("failed to search");
assert!(top_docs.is_empty());
let reader_ = reader.clone();
let search = task::spawn_blocking(move || {
reader_.reload().expect("failed to reload reader");
reader_
.searcher()
.search(&query, &TopDocs::with_limit(10))
.expect("failed to search")
});
let top_docs: Vec<(Score, DocAddress)> = search.await.expect("failed to search");
assert_eq!(top_docs.len(), 1);
for (_score, addr) in top_docs {
let _doc: TantivyDocument = reader
.searcher()
.doc_async(addr)
.await
.expect("failed to read document");
}
}