You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

55 lines
1.8KB

  1. use clap::ArgMatches;
  2. use std::convert::From;
  3. use std::path::Path;
  4. use std::path::PathBuf;
  5. use tantivy;
  6. use tantivy::Index;
  7. use tantivy::query::QueryParser;
  8. use tantivy::schema::Field;
  9. use serde_json;
  10. use tantivy::schema::FieldType;
  11. use tantivy::tokenizer::*;
  12. pub fn run_search_cli(matches: &ArgMatches) -> Result<(), String> {
  13. let index_directory = PathBuf::from(matches.value_of("index").unwrap());
  14. let query = matches.value_of("query").unwrap();
  15. run_search(&index_directory, &query)
  16. .map_err(|e| format!("{:?}", e))
  17. }
  18. fn run_search(directory: &Path, query: &str) -> tantivy::Result<()> {
  19. let index = Index::open(directory)?;
  20. let schema = index.schema();
  21. let default_fields: Vec<Field> = schema
  22. .fields()
  23. .iter()
  24. .enumerate()
  25. .filter(
  26. |&(_, ref field_entry) | {
  27. match *field_entry.field_type() {
  28. FieldType::Str(ref text_field_options) => {
  29. text_field_options.get_indexing_options().is_some()
  30. },
  31. _ => false
  32. }
  33. }
  34. )
  35. .map(|(i, _)| Field(i as u32))
  36. .collect();
  37. let query_parser = QueryParser::new(schema.clone(), default_fields, index.tokenizers().clone());
  38. let query = query_parser.parse_query(query)?;
  39. let searcher = index.searcher();
  40. let weight = query.weight(&searcher)?;
  41. let schema = index.schema();
  42. for segment_reader in searcher.segment_readers() {
  43. let mut scorer = weight.scorer(segment_reader)?;
  44. while scorer.advance() {
  45. let doc_id = scorer.doc();
  46. let doc = segment_reader.doc(doc_id)?;
  47. let named_doc = schema.to_named_doc(&doc);
  48. println!("{}", serde_json::to_string(&named_doc).unwrap());
  49. }
  50. }
  51. Ok(())
  52. }