|
| 1 | +use tantivy::collector::TopDocs; |
| 2 | +use tantivy::query::QueryParser; |
| 3 | +use tantivy::schema::*; |
| 4 | +use tantivy::{doc, Index, ReloadPolicy, Result}; |
| 5 | +use tempfile::TempDir; |
| 6 | + |
| 7 | +fn main() -> Result<()> { |
| 8 | + let index_path = TempDir::new()?; |
| 9 | + |
| 10 | + let mut schema_builder = Schema::builder(); |
| 11 | + schema_builder.add_text_field("title", TEXT | STORED); |
| 12 | + schema_builder.add_text_field("body", TEXT); |
| 13 | + let schema = schema_builder.build(); |
| 14 | + |
| 15 | + let title = schema.get_field("title").unwrap(); |
| 16 | + let body = schema.get_field("body").unwrap(); |
| 17 | + |
| 18 | + let index = Index::create_in_dir(&index_path, schema)?; |
| 19 | + |
| 20 | + let mut index_writer = index.writer(50_000_000)?; |
| 21 | + |
| 22 | + index_writer.add_document(doc!( |
| 23 | + title => "The Old Man and the Sea", |
| 24 | + body => "He was an old man who fished alone in a skiff in the Gulf Stream and he had gone \ |
| 25 | + eighty-four days now without taking a fish.", |
| 26 | + ))?; |
| 27 | + |
| 28 | + index_writer.add_document(doc!( |
| 29 | + title => "Of Mice and Men", |
| 30 | + body => "A few miles south of Soledad, the Salinas River drops in close to the hillside \ |
| 31 | + bank and runs deep and green. The water is warm too, for it has slipped twinkling \ |
| 32 | + over the yellow sands in the sunlight before reaching the narrow pool. On one \ |
| 33 | + side of the river the golden foothill slopes curve up to the strong and rocky \ |
| 34 | + Gabilan Mountains, but on the valley side the water is lined with trees—willows \ |
| 35 | + fresh and green with every spring, carrying in their lower leaf junctures the \ |
| 36 | + debris of the winter’s flooding; and sycamores with mottled, white, recumbent \ |
| 37 | + limbs and branches that arch over the pool" |
| 38 | + ))?; |
| 39 | + |
| 40 | + // Multivalued field just need to be repeated. |
| 41 | + index_writer.add_document(doc!( |
| 42 | + title => "Frankenstein", |
| 43 | + title => "The Modern Prometheus", |
| 44 | + body => "You will rejoice to hear that no disaster has accompanied the commencement of an \ |
| 45 | + enterprise which you have regarded with such evil forebodings. I arrived here \ |
| 46 | + yesterday, and my first task is to assure my dear sister of my welfare and \ |
| 47 | + increasing confidence in the success of my undertaking." |
| 48 | + ))?; |
| 49 | + |
| 50 | + index_writer.commit()?; |
| 51 | + |
| 52 | + let reader = index |
| 53 | + .reader_builder() |
| 54 | + .reload_policy(ReloadPolicy::OnCommit) |
| 55 | + .try_into()?; |
| 56 | + |
| 57 | + let searcher = reader.searcher(); |
| 58 | + |
| 59 | + let query_parser = QueryParser::for_index(&index, vec![title, body]); |
| 60 | + // This will match documents containing the phrase "in the" |
| 61 | + // followed by some word starting with "su", |
| 62 | + // i.e. it will match "in the sunlight" and "in the success", |
| 63 | + // but not "in the Gulf Stream". |
| 64 | + let query = query_parser.parse_query("\"in the su\"*")?; |
| 65 | + |
| 66 | + let top_docs = searcher.search(&query, &TopDocs::with_limit(10))?; |
| 67 | + let mut titles = top_docs |
| 68 | + .into_iter() |
| 69 | + .map(|(_score, doc_address)| { |
| 70 | + let doc = searcher.doc(doc_address)?; |
| 71 | + let title = doc.get_first(title).unwrap().as_text().unwrap().to_owned(); |
| 72 | + Ok(title) |
| 73 | + }) |
| 74 | + .collect::<Result<Vec<_>>>()?; |
| 75 | + titles.sort_unstable(); |
| 76 | + assert_eq!(titles, ["Frankenstein", "Of Mice and Men"]); |
| 77 | + |
| 78 | + Ok(()) |
| 79 | +} |
0 commit comments