diff --git a/TODO.md b/TODO.md index 2c8a3b620..d5c482bbb 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,15 @@ -query explain, complete, proper term names +lenient mode for query parser +phrase queries +masks for union +documentation +query explain with proper term names + +Arc for the schema pass over offset from previous block error management add merge policy find solution to "I have a docaddress but the segment does not exist anymore problem" doc values for other types -documentation use skip list for each blocks find a clear way to put the tokenized/untokenized thing upstream index frequent bigrams @@ -12,14 +17,11 @@ reconsider the first byte == field in the [u8] repr of a term. good cli good cli based demo intersection -masks for union -lenient mode for query parser WAND rethink query iteration mechanics / API (should we setScorer, should collector take different objects?) -Dig issue monoids idea -phrase queries +Dig issue monoids idea for collectors sort by fast field date geo search -deletes \ No newline at end of file +deletes diff --git a/src/query/query_parser.rs b/src/query/query_parser.rs index 53fc96a68..bbe009b9f 100644 --- a/src/query/query_parser.rs +++ b/src/query/query_parser.rs @@ -4,8 +4,7 @@ use collector::Collector; use core::searcher::Searcher; use common::TimerTree; use query::{Query, MultiTermQuery}; -use schema::Schema; -use schema::{Term, Field}; +use schema::{Schema, Term, Field, FieldEntry}; use analyzer::SimpleTokenizer; use analyzer::StreamingIterator; use DocAddress; @@ -15,6 +14,7 @@ use query::Explanation; pub enum ParsingError { SyntaxError, FieldDoesNotExist(String), + ExpectedU32(String, String), } pub struct QueryParser { @@ -80,23 +80,45 @@ impl QueryParser { schema: schema, default_fields: default_fields, } - } - - // TODO check that the term is str. - // we only support str field for the moment + } + + + fn transform_field_and_value(&self, field: Field, val: &str) -> Result, ParsingError> { + let field_entry = self.schema.get_field_entry(field); + Ok(match field_entry { + &FieldEntry::Text(_, _) => { + compute_terms(field, val) + }, + &FieldEntry::U32(ref field_name, _) => { + let u32_parsed: u32 = try!(val + .parse::() + .map_err(|_| { + ParsingError::ExpectedU32(field_name.clone(), String::from(val)) + }) + ); + vec!(Term::from_field_u32(field, u32_parsed)) + } + }) + + } + + fn transform_literal(&self, literal: Literal) -> Result, ParsingError> { match literal { Literal::DefaultField(val) => { - let terms = self.default_fields - .iter() - .cloned() - .flat_map(|field| compute_terms(field, &val)) - .collect(); + let mut terms = Vec::new(); + for &field in &self.default_fields { + let extra_terms = try!(self.transform_field_and_value(field, &val)); + terms.extend_from_slice(&extra_terms); + } Ok(terms) }, Literal::WithField(field_name, val) => { match self.schema.get_field(&field_name) { - Some(field) => Ok(compute_terms(field, &val)), + Some(field) => { + let terms = try!(self.transform_field_and_value(field, &val)); + Ok(terms) + }, None => Err(ParsingError::FieldDoesNotExist(field_name)) } } @@ -107,7 +129,7 @@ impl QueryParser { match parser(query_language).parse(query.trim()) { Ok(literals) => { let mut terms_result: Vec = Vec::new(); - for literal in literals.0.into_iter() { + for literal in literals.0 { let literal_terms = try!(self.transform_literal(literal)); terms_result.extend_from_slice(&literal_terms); }