Compare commits

...

2 Commits

Author SHA1 Message Date
Paul Masurel
937485321a Rebase and fixing unit test 2023-01-18 10:15:16 +09:00
Pascal Seitz
e3be14e7d8 start migrate Field to &str
start migrate Field to &str in preparation of columnar
return Result for get_field
2023-01-18 10:02:19 +09:00
30 changed files with 294 additions and 247 deletions

View File

@@ -14,7 +14,7 @@ use fastfield_codecs::Column;
// Importing tantivy... // Importing tantivy...
use tantivy::collector::{Collector, SegmentCollector}; use tantivy::collector::{Collector, SegmentCollector};
use tantivy::query::QueryParser; use tantivy::query::QueryParser;
use tantivy::schema::{Field, Schema, FAST, INDEXED, TEXT}; use tantivy::schema::{Schema, FAST, INDEXED, TEXT};
use tantivy::{doc, Index, Score, SegmentReader}; use tantivy::{doc, Index, Score, SegmentReader};
#[derive(Default)] #[derive(Default)]
@@ -52,11 +52,11 @@ impl Stats {
} }
struct StatsCollector { struct StatsCollector {
field: Field, field: String,
} }
impl StatsCollector { impl StatsCollector {
fn with_field(field: Field) -> StatsCollector { fn with_field(field: String) -> StatsCollector {
StatsCollector { field } StatsCollector { field }
} }
} }
@@ -73,7 +73,7 @@ impl Collector for StatsCollector {
_segment_local_id: u32, _segment_local_id: u32,
segment_reader: &SegmentReader, segment_reader: &SegmentReader,
) -> tantivy::Result<StatsSegmentCollector> { ) -> tantivy::Result<StatsSegmentCollector> {
let fast_field_reader = segment_reader.fast_fields().u64(self.field)?; let fast_field_reader = segment_reader.fast_fields().u64(&self.field)?;
Ok(StatsSegmentCollector { Ok(StatsSegmentCollector {
fast_field_reader, fast_field_reader,
stats: Stats::default(), stats: Stats::default(),
@@ -171,7 +171,9 @@ fn main() -> tantivy::Result<()> {
// here we want to get a hit on the 'ken' in Frankenstein // here we want to get a hit on the 'ken' in Frankenstein
let query = query_parser.parse_query("broom")?; let query = query_parser.parse_query("broom")?;
if let Some(stats) = searcher.search(&query, &StatsCollector::with_field(price))? { if let Some(stats) =
searcher.search(&query, &StatsCollector::with_field("price".to_string()))?
{
println!("count: {}", stats.count()); println!("count: {}", stats.count());
println!("mean: {}", stats.mean()); println!("mean: {}", stats.mean());
println!("standard deviation: {}", stats.standard_deviation()); println!("standard deviation: {}", stats.standard_deviation());

View File

@@ -27,7 +27,7 @@ fn main() -> Result<()> {
reader.reload()?; reader.reload()?;
let searcher = reader.searcher(); let searcher = reader.searcher();
// The end is excluded i.e. here we are searching up to 1969 // The end is excluded i.e. here we are searching up to 1969
let docs_in_the_sixties = RangeQuery::new_u64(year_field, 1960..1970); let docs_in_the_sixties = RangeQuery::new_u64("year".to_string(), 1960..1970);
// Uses a Count collector to sum the total number of docs in the range // Uses a Count collector to sum the total number of docs in the range
let num_60s_books = searcher.search(&docs_in_the_sixties, &Count)?; let num_60s_books = searcher.search(&docs_in_the_sixties, &Count)?;
assert_eq!(num_60s_books, 10); assert_eq!(num_60s_books, 10);

View File

@@ -4,7 +4,7 @@ use std::sync::{Arc, RwLock, Weak};
use tantivy::collector::TopDocs; use tantivy::collector::TopDocs;
use tantivy::query::QueryParser; use tantivy::query::QueryParser;
use tantivy::schema::{Field, Schema, FAST, TEXT}; use tantivy::schema::{Schema, FAST, TEXT};
use tantivy::{ use tantivy::{
doc, DocAddress, DocId, Index, IndexReader, Opstamp, Searcher, SearcherGeneration, SegmentId, doc, DocAddress, DocId, Index, IndexReader, Opstamp, Searcher, SearcherGeneration, SegmentId,
SegmentReader, Warmer, SegmentReader, Warmer,
@@ -25,13 +25,13 @@ pub trait PriceFetcher: Send + Sync + 'static {
} }
struct DynamicPriceColumn { struct DynamicPriceColumn {
field: Field, field: String,
price_cache: RwLock<HashMap<(SegmentId, Option<Opstamp>), Arc<Vec<Price>>>>, price_cache: RwLock<HashMap<(SegmentId, Option<Opstamp>), Arc<Vec<Price>>>>,
price_fetcher: Box<dyn PriceFetcher>, price_fetcher: Box<dyn PriceFetcher>,
} }
impl DynamicPriceColumn { impl DynamicPriceColumn {
pub fn with_product_id_field<T: PriceFetcher>(field: Field, price_fetcher: T) -> Self { pub fn with_product_id_field<T: PriceFetcher>(field: String, price_fetcher: T) -> Self {
DynamicPriceColumn { DynamicPriceColumn {
field, field,
price_cache: Default::default(), price_cache: Default::default(),
@@ -48,7 +48,7 @@ impl Warmer for DynamicPriceColumn {
fn warm(&self, searcher: &Searcher) -> tantivy::Result<()> { fn warm(&self, searcher: &Searcher) -> tantivy::Result<()> {
for segment in searcher.segment_readers() { for segment in searcher.segment_readers() {
let key = (segment.segment_id(), segment.delete_opstamp()); let key = (segment.segment_id(), segment.delete_opstamp());
let product_id_reader = segment.fast_fields().u64(self.field)?; let product_id_reader = segment.fast_fields().u64(&self.field)?;
let product_ids: Vec<ProductId> = segment let product_ids: Vec<ProductId> = segment
.doc_ids_alive() .doc_ids_alive()
.map(|doc| product_id_reader.get_val(doc)) .map(|doc| product_id_reader.get_val(doc))
@@ -123,7 +123,7 @@ fn main() -> tantivy::Result<()> {
let price_table = ExternalPriceTable::default(); let price_table = ExternalPriceTable::default();
let price_dynamic_column = Arc::new(DynamicPriceColumn::with_product_id_field( let price_dynamic_column = Arc::new(DynamicPriceColumn::with_product_id_field(
product_id, "product_id".to_string(),
price_table.clone(), price_table.clone(),
)); ));
price_table.update_price(OLIVE_OIL, 12); price_table.update_price(OLIVE_OIL, 12);

View File

@@ -94,10 +94,7 @@ impl BucketAggregationWithAccessor {
BucketAggregationType::Terms(TermsAggregation { BucketAggregationType::Terms(TermsAggregation {
field: field_name, .. field: field_name, ..
}) => { }) => {
let field = reader let field = reader.schema().get_field(field_name)?;
.schema()
.get_field(field_name)
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))?;
inverted_index = Some(reader.inverted_index(field)?); inverted_index = Some(reader.inverted_index(field)?);
get_ff_reader_and_validate(reader, field_name, Cardinality::MultiValues)? get_ff_reader_and_validate(reader, field_name, Cardinality::MultiValues)?
} }
@@ -195,10 +192,7 @@ fn get_ff_reader_and_validate(
field_name: &str, field_name: &str,
cardinality: Cardinality, cardinality: Cardinality,
) -> crate::Result<(FastFieldAccessor, Type)> { ) -> crate::Result<(FastFieldAccessor, Type)> {
let field = reader let field = reader.schema().get_field(field_name)?;
.schema()
.get_field(field_name)
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))?;
let field_type = reader.schema().get_field_entry(field).field_type(); let field_type = reader.schema().get_field_entry(field).field_type();
if let Some((_ff_type, field_cardinality)) = type_and_cardinality(field_type) { if let Some((_ff_type, field_cardinality)) = type_and_cardinality(field_type) {
@@ -218,10 +212,10 @@ fn get_ff_reader_and_validate(
let ff_fields = reader.fast_fields(); let ff_fields = reader.fast_fields();
match cardinality { match cardinality {
Cardinality::SingleValue => ff_fields Cardinality::SingleValue => ff_fields
.u64_lenient(field) .u64_lenient(field_name)
.map(|field| (FastFieldAccessor::Single(field), field_type.value_type())), .map(|field| (FastFieldAccessor::Single(field), field_type.value_type())),
Cardinality::MultiValues => ff_fields Cardinality::MultiValues => ff_fields
.u64s_lenient(field) .u64s_lenient(field_name)
.map(|field| (FastFieldAccessor::Multi(field), field_type.value_type())), .map(|field| (FastFieldAccessor::Multi(field), field_type.value_type())),
} }
} }

View File

@@ -548,9 +548,7 @@ pub(crate) fn intermediate_histogram_buckets_to_final_buckets(
}; };
// If we have a date type on the histogram buckets, we add the `key_as_string` field as rfc339 // If we have a date type on the histogram buckets, we add the `key_as_string` field as rfc339
let field = schema let field = schema.get_field(&histogram_req.field)?;
.get_field(&histogram_req.field)
.ok_or_else(|| TantivyError::FieldNotFound(histogram_req.field.to_string()))?;
if schema.get_field_entry(field).field_type().is_date() { if schema.get_field_entry(field).field_type().is_date() {
for bucket in buckets.iter_mut() { for bucket in buckets.iter_mut() {
if let crate::aggregation::Key::F64(val) = bucket.key { if let crate::aggregation::Key::F64(val) = bucket.key {

View File

@@ -26,7 +26,6 @@ use super::{format_date, Key, SerializedKey, VecWithNames};
use crate::aggregation::agg_result::{AggregationResults, BucketEntries, BucketEntry}; use crate::aggregation::agg_result::{AggregationResults, BucketEntries, BucketEntry};
use crate::aggregation::bucket::TermsAggregationInternal; use crate::aggregation::bucket::TermsAggregationInternal;
use crate::schema::Schema; use crate::schema::Schema;
use crate::TantivyError;
/// Contains the intermediate aggregation result, which is optimized to be merged with other /// Contains the intermediate aggregation result, which is optimized to be merged with other
/// intermediate results. /// intermediate results.
@@ -658,9 +657,7 @@ impl IntermediateRangeBucketEntry {
// If we have a date type on the histogram buckets, we add the `key_as_string` field as // If we have a date type on the histogram buckets, we add the `key_as_string` field as
// rfc339 // rfc339
let field = schema let field = schema.get_field(&range_req.field)?;
.get_field(&range_req.field)
.ok_or_else(|| TantivyError::FieldNotFound(range_req.field.to_string()))?;
if schema.get_field_entry(field).field_type().is_date() { if schema.get_field_entry(field).field_type().is_date() {
if let Some(val) = range_bucket_entry.to { if let Some(val) = range_bucket_entry.to {
let key_as_string = format_date(val as i64)?; let key_as_string = format_date(val as i64)?;

View File

@@ -130,7 +130,7 @@ where
let fast_field_reader = segment_reader let fast_field_reader = segment_reader
.fast_fields() .fast_fields()
.typed_fast_field_reader(self.field)?; .typed_fast_field_reader(schema.get_field_name(self.field))?;
let segment_collector = self let segment_collector = self
.collector .collector

View File

@@ -5,7 +5,7 @@ use fastfield_codecs::Column;
use crate::collector::{Collector, SegmentCollector}; use crate::collector::{Collector, SegmentCollector};
use crate::fastfield::FastValue; use crate::fastfield::FastValue;
use crate::schema::{Field, Type}; use crate::schema::Type;
use crate::{DocId, Score}; use crate::{DocId, Score};
/// Histogram builds an histogram of the values of a fastfield for the /// Histogram builds an histogram of the values of a fastfield for the
@@ -28,7 +28,7 @@ pub struct HistogramCollector {
min_value: u64, min_value: u64,
num_buckets: usize, num_buckets: usize,
divider: DividerU64, divider: DividerU64,
field: Field, field: String,
} }
impl HistogramCollector { impl HistogramCollector {
@@ -46,7 +46,7 @@ impl HistogramCollector {
/// # Disclaimer /// # Disclaimer
/// This function panics if the field given is of type f64. /// This function panics if the field given is of type f64.
pub fn new<TFastValue: FastValue>( pub fn new<TFastValue: FastValue>(
field: Field, field: String,
min_value: TFastValue, min_value: TFastValue,
bucket_width: u64, bucket_width: u64,
num_buckets: usize, num_buckets: usize,
@@ -112,7 +112,7 @@ impl Collector for HistogramCollector {
_segment_local_id: crate::SegmentOrdinal, _segment_local_id: crate::SegmentOrdinal,
segment: &crate::SegmentReader, segment: &crate::SegmentReader,
) -> crate::Result<Self::Child> { ) -> crate::Result<Self::Child> {
let ff_reader = segment.fast_fields().u64_lenient(self.field)?; let ff_reader = segment.fast_fields().u64_lenient(&self.field)?;
Ok(SegmentHistogramCollector { Ok(SegmentHistogramCollector {
histogram_computer: HistogramComputer { histogram_computer: HistogramComputer {
counts: vec![0; self.num_buckets], counts: vec![0; self.num_buckets],
@@ -211,13 +211,13 @@ mod tests {
#[test] #[test]
fn test_no_segments() -> crate::Result<()> { fn test_no_segments() -> crate::Result<()> {
let mut schema_builder = Schema::builder(); let mut schema_builder = Schema::builder();
let val_field = schema_builder.add_u64_field("val_field", FAST); schema_builder.add_u64_field("val_field", FAST);
let schema = schema_builder.build(); let schema = schema_builder.build();
let index = Index::create_in_ram(schema); let index = Index::create_in_ram(schema);
let reader = index.reader()?; let reader = index.reader()?;
let searcher = reader.searcher(); let searcher = reader.searcher();
let all_query = AllQuery; let all_query = AllQuery;
let histogram_collector = HistogramCollector::new(val_field, 0u64, 2, 5); let histogram_collector = HistogramCollector::new("val_field".to_string(), 0u64, 2, 5);
let histogram = searcher.search(&all_query, &histogram_collector)?; let histogram = searcher.search(&all_query, &histogram_collector)?;
assert_eq!(histogram, vec![0; 5]); assert_eq!(histogram, vec![0; 5]);
Ok(()) Ok(())
@@ -238,7 +238,8 @@ mod tests {
let reader = index.reader()?; let reader = index.reader()?;
let searcher = reader.searcher(); let searcher = reader.searcher();
let all_query = AllQuery; let all_query = AllQuery;
let histogram_collector = HistogramCollector::new(val_field, -20i64, 10u64, 4); let histogram_collector =
HistogramCollector::new("val_field".to_string(), -20i64, 10u64, 4);
let histogram = searcher.search(&all_query, &histogram_collector)?; let histogram = searcher.search(&all_query, &histogram_collector)?;
assert_eq!(histogram, vec![1, 1, 0, 1]); assert_eq!(histogram, vec![1, 1, 0, 1]);
Ok(()) Ok(())
@@ -262,7 +263,8 @@ mod tests {
let reader = index.reader()?; let reader = index.reader()?;
let searcher = reader.searcher(); let searcher = reader.searcher();
let all_query = AllQuery; let all_query = AllQuery;
let histogram_collector = HistogramCollector::new(val_field, -20i64, 10u64, 4); let histogram_collector =
HistogramCollector::new("val_field".to_string(), -20i64, 10u64, 4);
let histogram = searcher.search(&all_query, &histogram_collector)?; let histogram = searcher.search(&all_query, &histogram_collector)?;
assert_eq!(histogram, vec![1, 1, 0, 1]); assert_eq!(histogram, vec![1, 1, 0, 1]);
Ok(()) Ok(())
@@ -285,7 +287,7 @@ mod tests {
let searcher = reader.searcher(); let searcher = reader.searcher();
let all_query = AllQuery; let all_query = AllQuery;
let week_histogram_collector = HistogramCollector::new( let week_histogram_collector = HistogramCollector::new(
date_field, "date_field".to_string(),
DateTime::from_primitive( DateTime::from_primitive(
Date::from_calendar_date(1980, Month::January, 1)?.with_hms(0, 0, 0)?, Date::from_calendar_date(1980, Month::January, 1)?.with_hms(0, 0, 0)?,
), ),

View File

@@ -155,7 +155,7 @@ impl SegmentCollector for TestSegmentCollector {
/// ///
/// This collector is mainly useful for tests. /// This collector is mainly useful for tests.
pub struct FastFieldTestCollector { pub struct FastFieldTestCollector {
field: Field, field: String,
} }
pub struct FastFieldSegmentCollector { pub struct FastFieldSegmentCollector {
@@ -164,7 +164,7 @@ pub struct FastFieldSegmentCollector {
} }
impl FastFieldTestCollector { impl FastFieldTestCollector {
pub fn for_field(field: Field) -> FastFieldTestCollector { pub fn for_field(field: String) -> FastFieldTestCollector {
FastFieldTestCollector { field } FastFieldTestCollector { field }
} }
} }
@@ -180,7 +180,7 @@ impl Collector for FastFieldTestCollector {
) -> crate::Result<FastFieldSegmentCollector> { ) -> crate::Result<FastFieldSegmentCollector> {
let reader = segment_reader let reader = segment_reader
.fast_fields() .fast_fields()
.u64(self.field) .u64(&self.field)
.expect("Requested field is not a fast field."); .expect("Requested field is not a fast field.");
Ok(FastFieldSegmentCollector { Ok(FastFieldSegmentCollector {
vals: Vec::new(), vals: Vec::new(),
@@ -238,7 +238,9 @@ impl Collector for BytesFastFieldTestCollector {
_segment_local_id: u32, _segment_local_id: u32,
segment_reader: &SegmentReader, segment_reader: &SegmentReader,
) -> crate::Result<BytesFastFieldSegmentCollector> { ) -> crate::Result<BytesFastFieldSegmentCollector> {
let reader = segment_reader.fast_fields().bytes(self.field)?; let reader = segment_reader
.fast_fields()
.bytes(segment_reader.schema().get_field_name(self.field))?;
Ok(BytesFastFieldSegmentCollector { Ok(BytesFastFieldSegmentCollector {
vals: Vec::new(), vals: Vec::new(),
reader, reader,

View File

@@ -156,7 +156,7 @@ impl CustomScorer<u64> for ScorerByField {
// The conversion will then happen only on the top-K docs. // The conversion will then happen only on the top-K docs.
let ff_reader = segment_reader let ff_reader = segment_reader
.fast_fields() .fast_fields()
.typed_fast_field_reader(self.field)?; .typed_fast_field_reader(segment_reader.schema().get_field_name(self.field))?;
Ok(ScorerByFastFieldReader { ff_reader }) Ok(ScorerByFastFieldReader { ff_reader })
} }
} }
@@ -454,7 +454,7 @@ impl TopDocs {
/// // In our case, we will get a reader for the popularity /// // In our case, we will get a reader for the popularity
/// // fast field. /// // fast field.
/// let popularity_reader = /// let popularity_reader =
/// segment_reader.fast_fields().u64(popularity).unwrap(); /// segment_reader.fast_fields().u64("popularity").unwrap();
/// ///
/// // We can now define our actual scoring function /// // We can now define our actual scoring function
/// move |doc: DocId, original_score: Score| { /// move |doc: DocId, original_score: Score| {
@@ -561,9 +561,9 @@ impl TopDocs {
/// // Note that this is implemented by using a `(u64, u64)` /// // Note that this is implemented by using a `(u64, u64)`
/// // as a score. /// // as a score.
/// let popularity_reader = /// let popularity_reader =
/// segment_reader.fast_fields().u64(popularity).unwrap(); /// segment_reader.fast_fields().u64("popularity").unwrap();
/// let boosted_reader = /// let boosted_reader =
/// segment_reader.fast_fields().u64(boosted).unwrap(); /// segment_reader.fast_fields().u64("boosted").unwrap();
/// ///
/// // We can now define our actual scoring function /// // We can now define our actual scoring function
/// move |doc: DocId| { /// move |doc: DocId| {

View File

@@ -231,7 +231,7 @@ impl IndexBuilder {
fn validate(&self) -> crate::Result<()> { fn validate(&self) -> crate::Result<()> {
if let Some(schema) = self.schema.as_ref() { if let Some(schema) = self.schema.as_ref() {
if let Some(sort_by_field) = self.index_settings.sort_by_field.as_ref() { if let Some(sort_by_field) = self.index_settings.sort_by_field.as_ref() {
let schema_field = schema.get_field(&sort_by_field.field).ok_or_else(|| { let schema_field = schema.get_field(&sort_by_field.field).map_err(|_| {
TantivyError::InvalidArgument(format!( TantivyError::InvalidArgument(format!(
"Field to sort index {} not found in schema", "Field to sort index {} not found in schema",
sort_by_field.field sort_by_field.field

View File

@@ -95,7 +95,8 @@ impl SegmentReader {
match field_entry.field_type() { match field_entry.field_type() {
FieldType::Facet(_) => { FieldType::Facet(_) => {
let term_ords_reader = self.fast_fields().u64s(field)?; let term_ords_reader =
self.fast_fields().u64s(self.schema.get_field_name(field))?;
let termdict = self let termdict = self
.termdict_composite .termdict_composite
.open_read(field) .open_read(field)

View File

@@ -25,7 +25,7 @@ mod tests {
index_writer.commit()?; index_writer.commit()?;
let searcher = index.reader()?.searcher(); let searcher = index.reader()?.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let bytes_reader = segment_reader.fast_fields().bytes(bytes_field).unwrap(); let bytes_reader = segment_reader.fast_fields().bytes("bytesfield").unwrap();
assert_eq!(bytes_reader.get_bytes(0), &[0u8, 1, 2, 3]); assert_eq!(bytes_reader.get_bytes(0), &[0u8, 1, 2, 3]);
assert!(bytes_reader.get_bytes(1).is_empty()); assert!(bytes_reader.get_bytes(1).is_empty());
assert_eq!(bytes_reader.get_bytes(2), &[255u8]); assert_eq!(bytes_reader.get_bytes(2), &[255u8]);
@@ -109,8 +109,7 @@ mod tests {
let searcher = create_index_for_test(FAST)?; let searcher = create_index_for_test(FAST)?;
assert_eq!(searcher.num_docs(), 1); assert_eq!(searcher.num_docs(), 1);
let fast_fields = searcher.segment_reader(0u32).fast_fields(); let fast_fields = searcher.segment_reader(0u32).fast_fields();
let field = searcher.schema().get_field("string_bytes").unwrap(); let fast_field_reader = fast_fields.bytes("string_bytes").unwrap();
let fast_field_reader = fast_fields.bytes(field).unwrap();
assert_eq!(fast_field_reader.get_bytes(0u32), b"tantivy"); assert_eq!(fast_field_reader.get_bytes(0u32), b"tantivy");
Ok(()) Ok(())
} }

View File

@@ -583,7 +583,7 @@ mod tests {
assert_eq!(searcher.segment_readers().len(), 1); assert_eq!(searcher.segment_readers().len(), 1);
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!( assert_eq!(
get_vals_for_docs(&text_fast_field, 0..5), get_vals_for_docs(&text_fast_field, 0..5),
@@ -622,7 +622,7 @@ mod tests {
assert_eq!(searcher.segment_readers().len(), 2); assert_eq!(searcher.segment_readers().len(), 2);
let segment_reader = searcher.segment_reader(1); let segment_reader = searcher.segment_reader(1);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!(get_vals_for_docs(&text_fast_field, 0..3), vec![0, 1, 0]); assert_eq!(get_vals_for_docs(&text_fast_field, 0..3), vec![0, 1, 0]);
} }
@@ -638,7 +638,7 @@ mod tests {
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!( assert_eq!(
get_vals_for_docs(&text_fast_field, 0..8), get_vals_for_docs(&text_fast_field, 0..8),
@@ -681,7 +681,7 @@ mod tests {
assert_eq!(searcher.segment_readers().len(), 1); assert_eq!(searcher.segment_readers().len(), 1);
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!(get_vals_for_docs(&text_fast_field, 0..6), vec![1, 0, 0, 2]); assert_eq!(get_vals_for_docs(&text_fast_field, 0..6), vec![1, 0, 0, 2]);
@@ -712,7 +712,7 @@ mod tests {
assert_eq!(searcher.segment_readers().len(), 2); assert_eq!(searcher.segment_readers().len(), 2);
let segment_reader = searcher.segment_reader(1); let segment_reader = searcher.segment_reader(1);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!(get_vals_for_docs(&text_fast_field, 0..2), vec![0, 1]); assert_eq!(get_vals_for_docs(&text_fast_field, 0..2), vec![0, 1]);
} }
@@ -728,7 +728,7 @@ mod tests {
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let text_fast_field = fast_fields.u64s(text_field).unwrap(); let text_fast_field = fast_fields.u64s("text").unwrap();
assert_eq!( assert_eq!(
get_vals_for_docs(&text_fast_field, 0..9), get_vals_for_docs(&text_fast_field, 0..9),
@@ -773,8 +773,8 @@ mod tests {
assert_eq!(searcher.segment_readers().len(), 1); assert_eq!(searcher.segment_readers().len(), 1);
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let date_fast_field = fast_fields.date(date_field).unwrap(); let date_fast_field = fast_fields.date("date").unwrap();
let dates_fast_field = fast_fields.dates(multi_date_field).unwrap(); let dates_fast_field = fast_fields.dates("multi_date").unwrap();
let mut dates = vec![]; let mut dates = vec![];
{ {
assert_eq!(date_fast_field.get_val(0).into_timestamp_micros(), 1i64); assert_eq!(date_fast_field.get_val(0).into_timestamp_micros(), 1i64);
@@ -1014,7 +1014,7 @@ mod tests {
let reader = index.reader().unwrap(); let reader = index.reader().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment = &searcher.segment_readers()[0]; let segment = &searcher.segment_readers()[0];
let field = segment.fast_fields().u64(num_field).unwrap(); let field = segment.fast_fields().u64("url_norm_hash").unwrap();
let numbers = vec![100, 200, 300]; let numbers = vec![100, 200, 300];
let test_range = |range: RangeInclusive<u64>| { let test_range = |range: RangeInclusive<u64>| {
@@ -1063,7 +1063,7 @@ mod tests {
let reader = index.reader().unwrap(); let reader = index.reader().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment = &searcher.segment_readers()[0]; let segment = &searcher.segment_readers()[0];
let field = segment.fast_fields().u64(num_field).unwrap(); let field = segment.fast_fields().u64("url_norm_hash").unwrap();
let numbers = vec![1000, 1001, 1003]; let numbers = vec![1000, 1001, 1003];
let test_range = |range: RangeInclusive<u64>| { let test_range = |range: RangeInclusive<u64>| {

View File

@@ -52,7 +52,7 @@ mod tests {
let searcher = index.reader()?.searcher(); let searcher = index.reader()?.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let mut vals = Vec::new(); let mut vals = Vec::new();
let multi_value_reader = segment_reader.fast_fields().u64s(field)?; let multi_value_reader = segment_reader.fast_fields().u64s("multifield")?;
{ {
multi_value_reader.get_vals(2, &mut vals); multi_value_reader.get_vals(2, &mut vals);
assert_eq!(&vals, &[4u64]); assert_eq!(&vals, &[4u64]);
@@ -229,7 +229,7 @@ mod tests {
let searcher = index.reader()?.searcher(); let searcher = index.reader()?.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let mut vals = Vec::new(); let mut vals = Vec::new();
let multi_value_reader = segment_reader.fast_fields().i64s(field).unwrap(); let multi_value_reader = segment_reader.fast_fields().i64s("multifield").unwrap();
multi_value_reader.get_vals(2, &mut vals); multi_value_reader.get_vals(2, &mut vals);
assert_eq!(&vals, &[-4i64]); assert_eq!(&vals, &[-4i64]);
multi_value_reader.get_vals(0, &mut vals); multi_value_reader.get_vals(0, &mut vals);
@@ -261,7 +261,7 @@ mod tests {
let searcher = index.reader()?.searcher(); let searcher = index.reader()?.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let mut vals = Vec::new(); let mut vals = Vec::new();
let multi_value_reader = segment_reader.fast_fields().bools(bool_field).unwrap(); let multi_value_reader = segment_reader.fast_fields().bools("multifield").unwrap();
multi_value_reader.get_vals(2, &mut vals); multi_value_reader.get_vals(2, &mut vals);
assert_eq!(&vals, &[false]); assert_eq!(&vals, &[false]);
multi_value_reader.get_vals(0, &mut vals); multi_value_reader.get_vals(0, &mut vals);

View File

@@ -159,7 +159,7 @@ mod tests {
let searcher = reader.searcher(); let searcher = reader.searcher();
let reader = searcher.segment_reader(0); let reader = searcher.segment_reader(0);
let date_ff_reader = reader.fast_fields().dates(date_field).unwrap(); let date_ff_reader = reader.fast_fields().dates("multi_date_field").unwrap();
let mut docids = vec![]; let mut docids = vec![];
date_ff_reader.get_docids_for_value_range( date_ff_reader.get_docids_for_value_range(
DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead), DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead),
@@ -173,7 +173,7 @@ mod tests {
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_date( count_multiples(RangeQuery::new_date(
date_field, "multi_date_field".to_string(),
DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead) DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead)
)), )),
1 1
@@ -226,7 +226,7 @@ mod tests {
let reader = searcher.segment_reader(0); let reader = searcher.segment_reader(0);
assert_eq!(reader.num_docs(), 5); assert_eq!(reader.num_docs(), 5);
let date_ff_reader = reader.fast_fields().dates(date_field).unwrap(); let date_ff_reader = reader.fast_fields().dates("multi_date_field").unwrap();
let mut docids = vec![]; let mut docids = vec![];
date_ff_reader.get_docids_for_value_range( date_ff_reader.get_docids_for_value_range(
DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead), DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead),
@@ -240,7 +240,7 @@ mod tests {
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_date( count_multiples(RangeQuery::new_date(
date_field, "multi_date_field".to_string(),
DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead) DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead)
)), )),
2 2
@@ -324,7 +324,7 @@ mod tests {
index_writer.commit()?; index_writer.commit()?;
let searcher = index.reader()?.searcher(); let searcher = index.reader()?.searcher();
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let field_reader = segment_reader.fast_fields().i64s(item_field)?; let field_reader = segment_reader.fast_fields().i64s("items")?;
assert_eq!(field_reader.min_value(), -2); assert_eq!(field_reader.min_value(), -2);
assert_eq!(field_reader.max_value(), 6); assert_eq!(field_reader.max_value(), 6);

View File

@@ -114,9 +114,11 @@ impl FastFieldReaders {
pub(crate) fn typed_fast_field_reader_with_idx<TFastValue: FastValue>( pub(crate) fn typed_fast_field_reader_with_idx<TFastValue: FastValue>(
&self, &self,
field: Field, field_name: &str,
index: usize, index: usize,
) -> crate::Result<Arc<dyn Column<TFastValue>>> { ) -> crate::Result<Arc<dyn Column<TFastValue>>> {
let field = self.schema.get_field(field_name)?;
let fast_field_slice = self.fast_field_data(field, index)?; let fast_field_slice = self.fast_field_data(field, index)?;
let bytes = fast_field_slice.read_bytes()?; let bytes = fast_field_slice.read_bytes()?;
let column = fastfield_codecs::open(bytes)?; let column = fastfield_codecs::open(bytes)?;
@@ -125,32 +127,37 @@ impl FastFieldReaders {
pub(crate) fn typed_fast_field_reader<TFastValue: FastValue>( pub(crate) fn typed_fast_field_reader<TFastValue: FastValue>(
&self, &self,
field: Field, field_name: &str,
) -> crate::Result<Arc<dyn Column<TFastValue>>> { ) -> crate::Result<Arc<dyn Column<TFastValue>>> {
self.typed_fast_field_reader_with_idx(field, 0) self.typed_fast_field_reader_with_idx(field_name, 0)
} }
pub(crate) fn typed_fast_field_multi_reader<TFastValue: FastValue>( pub(crate) fn typed_fast_field_multi_reader<TFastValue: FastValue>(
&self, &self,
field: Field, field_name: &str,
) -> crate::Result<MultiValuedFastFieldReader<TFastValue>> { ) -> crate::Result<MultiValuedFastFieldReader<TFastValue>> {
let idx_reader = self.typed_fast_field_reader(field)?; let idx_reader = self.typed_fast_field_reader(field_name)?;
let vals_reader = self.typed_fast_field_reader_with_idx(field, 1)?; let vals_reader = self.typed_fast_field_reader_with_idx(field_name, 1)?;
Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader)) Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader))
} }
/// Returns the `u64` fast field reader reader associated with `field`. /// Returns the `u64` fast field reader reader associated with `field`.
/// ///
/// If `field` is not a u64 fast field, this method returns an Error. /// If `field` is not a u64 fast field, this method returns an Error.
pub fn u64(&self, field: Field) -> crate::Result<Arc<dyn Column<u64>>> { pub fn u64(&self, field_name: &str) -> crate::Result<Arc<dyn Column<u64>>> {
self.check_type(field, FastType::U64, Cardinality::SingleValue)?; self.check_type(
self.typed_fast_field_reader(field) self.schema.get_field(field_name)?,
FastType::U64,
Cardinality::SingleValue,
)?;
self.typed_fast_field_reader(field_name)
} }
/// Returns the `ip` fast field reader reader associated to `field`. /// Returns the `ip` fast field reader reader associated to `field`.
/// ///
/// If `field` is not a u128 fast field, this method returns an Error. /// If `field` is not a u128 fast field, this method returns an Error.
pub fn ip_addr(&self, field: Field) -> crate::Result<Arc<dyn Column<Ipv6Addr>>> { pub fn ip_addr(&self, field_name: &str) -> crate::Result<Arc<dyn Column<Ipv6Addr>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::U128, Cardinality::SingleValue)?; self.check_type(field, FastType::U128, Cardinality::SingleValue)?;
let bytes = self.fast_field_data(field, 0)?.read_bytes()?; let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
Ok(open_u128::<Ipv6Addr>(bytes)?) Ok(open_u128::<Ipv6Addr>(bytes)?)
@@ -159,9 +166,13 @@ impl FastFieldReaders {
/// Returns the `ip` fast field reader reader associated to `field`. /// Returns the `ip` fast field reader reader associated to `field`.
/// ///
/// If `field` is not a u128 fast field, this method returns an Error. /// If `field` is not a u128 fast field, this method returns an Error.
pub fn ip_addrs(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<Ipv6Addr>> { pub fn ip_addrs(
&self,
field_name: &str,
) -> crate::Result<MultiValuedFastFieldReader<Ipv6Addr>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::U128, Cardinality::MultiValues)?; self.check_type(field, FastType::U128, Cardinality::MultiValues)?;
let idx_reader: Arc<dyn Column<u64>> = self.typed_fast_field_reader(field)?; let idx_reader: Arc<dyn Column<u64>> = self.typed_fast_field_reader(field_name)?;
let bytes = self.fast_field_data(field, 1)?.read_bytes()?; let bytes = self.fast_field_data(field, 1)?.read_bytes()?;
let vals_reader = open_u128::<Ipv6Addr>(bytes)?; let vals_reader = open_u128::<Ipv6Addr>(bytes)?;
@@ -172,7 +183,8 @@ impl FastFieldReaders {
/// Returns the `u128` fast field reader reader associated to `field`. /// Returns the `u128` fast field reader reader associated to `field`.
/// ///
/// If `field` is not a u128 fast field, this method returns an Error. /// If `field` is not a u128 fast field, this method returns an Error.
pub(crate) fn u128(&self, field: Field) -> crate::Result<Arc<dyn Column<u128>>> { pub(crate) fn u128(&self, field_name: &str) -> crate::Result<Arc<dyn Column<u128>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::U128, Cardinality::SingleValue)?; self.check_type(field, FastType::U128, Cardinality::SingleValue)?;
let bytes = self.fast_field_data(field, 0)?.read_bytes()?; let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
Ok(open_u128::<u128>(bytes)?) Ok(open_u128::<u128>(bytes)?)
@@ -181,9 +193,11 @@ impl FastFieldReaders {
/// Returns the `u128` multi-valued fast field reader reader associated to `field`. /// Returns the `u128` multi-valued fast field reader reader associated to `field`.
/// ///
/// If `field` is not a u128 multi-valued fast field, this method returns an Error. /// If `field` is not a u128 multi-valued fast field, this method returns an Error.
pub fn u128s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u128>> { pub fn u128s(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<u128>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::U128, Cardinality::MultiValues)?; self.check_type(field, FastType::U128, Cardinality::MultiValues)?;
let idx_reader: Arc<dyn Column<u64>> = self.typed_fast_field_reader(field)?; let idx_reader: Arc<dyn Column<u64>> =
self.typed_fast_field_reader(self.schema.get_field_name(field))?;
let bytes = self.fast_field_data(field, 1)?.read_bytes()?; let bytes = self.fast_field_data(field, 1)?.read_bytes()?;
let vals_reader = open_u128::<u128>(bytes)?; let vals_reader = open_u128::<u128>(bytes)?;
@@ -196,80 +210,88 @@ impl FastFieldReaders {
/// ///
/// If not, the fastfield reader will returns the u64-value associated with the original /// If not, the fastfield reader will returns the u64-value associated with the original
/// FastValue. /// FastValue.
pub fn u64_lenient(&self, field: Field) -> crate::Result<Arc<dyn Column<u64>>> { pub fn u64_lenient(&self, field_name: &str) -> crate::Result<Arc<dyn Column<u64>>> {
self.typed_fast_field_reader(field) self.typed_fast_field_reader(field_name)
} }
/// Returns the `i64` fast field reader reader associated with `field`. /// Returns the `i64` fast field reader reader associated with `field`.
/// ///
/// If `field` is not a i64 fast field, this method returns an Error. /// If `field` is not a i64 fast field, this method returns an Error.
pub fn i64(&self, field: Field) -> crate::Result<Arc<dyn Column<i64>>> { pub fn i64(&self, field_name: &str) -> crate::Result<Arc<dyn Column<i64>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::I64, Cardinality::SingleValue)?; self.check_type(field, FastType::I64, Cardinality::SingleValue)?;
self.typed_fast_field_reader(field) self.typed_fast_field_reader(self.schema.get_field_name(field))
} }
/// Returns the `date` fast field reader reader associated with `field`. /// Returns the `date` fast field reader reader associated with `field`.
/// ///
/// If `field` is not a date fast field, this method returns an Error. /// If `field` is not a date fast field, this method returns an Error.
pub fn date(&self, field: Field) -> crate::Result<Arc<dyn Column<DateTime>>> { pub fn date(&self, field_name: &str) -> crate::Result<Arc<dyn Column<DateTime>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::Date, Cardinality::SingleValue)?; self.check_type(field, FastType::Date, Cardinality::SingleValue)?;
self.typed_fast_field_reader(field) self.typed_fast_field_reader(field_name)
} }
/// Returns the `f64` fast field reader reader associated with `field`. /// Returns the `f64` fast field reader reader associated with `field`.
/// ///
/// If `field` is not a f64 fast field, this method returns an Error. /// If `field` is not a f64 fast field, this method returns an Error.
pub fn f64(&self, field: Field) -> crate::Result<Arc<dyn Column<f64>>> { pub fn f64(&self, field_name: &str) -> crate::Result<Arc<dyn Column<f64>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::F64, Cardinality::SingleValue)?; self.check_type(field, FastType::F64, Cardinality::SingleValue)?;
self.typed_fast_field_reader(field) self.typed_fast_field_reader(field_name)
} }
/// Returns the `bool` fast field reader reader associated with `field`. /// Returns the `bool` fast field reader reader associated with `field`.
/// ///
/// If `field` is not a bool fast field, this method returns an Error. /// If `field` is not a bool fast field, this method returns an Error.
pub fn bool(&self, field: Field) -> crate::Result<Arc<dyn Column<bool>>> { pub fn bool(&self, field_name: &str) -> crate::Result<Arc<dyn Column<bool>>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::Bool, Cardinality::SingleValue)?; self.check_type(field, FastType::Bool, Cardinality::SingleValue)?;
self.typed_fast_field_reader(field) self.typed_fast_field_reader(field_name)
} }
/// Returns a `u64s` multi-valued fast field reader reader associated with `field`. /// Returns a `u64s` multi-valued fast field reader reader associated with `field`.
/// ///
/// If `field` is not a u64 multi-valued fast field, this method returns an Error. /// If `field` is not a u64 multi-valued fast field, this method returns an Error.
pub fn u64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u64>> { pub fn u64s(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<u64>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::U64, Cardinality::MultiValues)?; self.check_type(field, FastType::U64, Cardinality::MultiValues)?;
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(field_name)
} }
/// Returns a `u64s` multi-valued fast field reader reader associated with `field`, regardless /// Returns a `u64s` multi-valued fast field reader reader associated with `field`, regardless
/// of whether the given field is effectively of type `u64` or not. /// of whether the given field is effectively of type `u64` or not.
/// ///
/// If `field` is not a u64 multi-valued fast field, this method returns an Error. /// If `field` is not a u64 multi-valued fast field, this method returns an Error.
pub fn u64s_lenient(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u64>> { pub fn u64s_lenient(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<u64>> {
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(field_name)
} }
/// Returns a `i64s` multi-valued fast field reader reader associated with `field`. /// Returns a `i64s` multi-valued fast field reader reader associated with `field`.
/// ///
/// If `field` is not a i64 multi-valued fast field, this method returns an Error. /// If `field` is not a i64 multi-valued fast field, this method returns an Error.
pub fn i64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<i64>> { pub fn i64s(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<i64>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::I64, Cardinality::MultiValues)?; self.check_type(field, FastType::I64, Cardinality::MultiValues)?;
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(self.schema.get_field_name(field))
} }
/// Returns a `f64s` multi-valued fast field reader reader associated with `field`. /// Returns a `f64s` multi-valued fast field reader reader associated with `field`.
/// ///
/// If `field` is not a f64 multi-valued fast field, this method returns an Error. /// If `field` is not a f64 multi-valued fast field, this method returns an Error.
pub fn f64s(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<f64>> { pub fn f64s(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<f64>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::F64, Cardinality::MultiValues)?; self.check_type(field, FastType::F64, Cardinality::MultiValues)?;
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(self.schema.get_field_name(field))
} }
/// Returns a `bools` multi-valued fast field reader reader associated with `field`. /// Returns a `bools` multi-valued fast field reader reader associated with `field`.
/// ///
/// If `field` is not a bool multi-valued fast field, this method returns an Error. /// If `field` is not a bool multi-valued fast field, this method returns an Error.
pub fn bools(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<bool>> { pub fn bools(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<bool>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::Bool, Cardinality::MultiValues)?; self.check_type(field, FastType::Bool, Cardinality::MultiValues)?;
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(self.schema.get_field_name(field))
} }
/// Returns a `time::OffsetDateTime` multi-valued fast field reader reader associated with /// Returns a `time::OffsetDateTime` multi-valued fast field reader reader associated with
@@ -277,15 +299,17 @@ impl FastFieldReaders {
/// ///
/// If `field` is not a `time::OffsetDateTime` multi-valued fast field, this method returns an /// If `field` is not a `time::OffsetDateTime` multi-valued fast field, this method returns an
/// Error. /// Error.
pub fn dates(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<DateTime>> { pub fn dates(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<DateTime>> {
let field = self.schema.get_field(field_name)?;
self.check_type(field, FastType::Date, Cardinality::MultiValues)?; self.check_type(field, FastType::Date, Cardinality::MultiValues)?;
self.typed_fast_field_multi_reader(field) self.typed_fast_field_multi_reader(self.schema.get_field_name(field))
} }
/// Returns the `bytes` fast field reader associated with `field`. /// Returns the `bytes` fast field reader associated with `field`.
/// ///
/// If `field` is not a bytes fast field, returns an Error. /// If `field` is not a bytes fast field, returns an Error.
pub fn bytes(&self, field: Field) -> crate::Result<BytesFastFieldReader> { pub fn bytes(&self, field_name: &str) -> crate::Result<BytesFastFieldReader> {
let field = self.schema.get_field(field_name)?;
let field_entry = self.schema.get_field_entry(field); let field_entry = self.schema.get_field_entry(field);
if let FieldType::Bytes(bytes_option) = field_entry.field_type() { if let FieldType::Bytes(bytes_option) = field_entry.field_type() {
if !bytes_option.is_fast() { if !bytes_option.is_fast() {

View File

@@ -99,7 +99,7 @@ pub(crate) fn expect_field_id_for_sort_field(
schema: &Schema, schema: &Schema,
sort_by_field: &IndexSortByField, sort_by_field: &IndexSortByField,
) -> crate::Result<Field> { ) -> crate::Result<Field> {
schema.get_field(&sort_by_field.field).ok_or_else(|| { schema.get_field(&sort_by_field.field).map_err(|_| {
TantivyError::InvalidArgument(format!( TantivyError::InvalidArgument(format!(
"field to sort index by not found: {:?}", "field to sort index by not found: {:?}",
sort_by_field.field sort_by_field.field
@@ -462,15 +462,14 @@ mod tests_indexsorting {
assert_eq!(searcher.segment_readers().len(), 1); assert_eq!(searcher.segment_readers().len(), 1);
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let my_number = index.schema().get_field("my_number").unwrap(); index.schema().get_field("my_number").unwrap();
let fast_field = fast_fields.u64(my_number).unwrap(); let fast_field = fast_fields.u64("my_number").unwrap();
assert_eq!(fast_field.get_val(0), 10u64); assert_eq!(fast_field.get_val(0), 10u64);
assert_eq!(fast_field.get_val(1), 20u64); assert_eq!(fast_field.get_val(1), 20u64);
assert_eq!(fast_field.get_val(2), 30u64); assert_eq!(fast_field.get_val(2), 30u64);
let multi_numbers = index.schema().get_field("multi_numbers").unwrap(); let multifield = fast_fields.u64s("multi_numbers").unwrap();
let multifield = fast_fields.u64s(multi_numbers).unwrap();
let mut vals = vec![]; let mut vals = vec![];
multifield.get_vals(0u32, &mut vals); multifield.get_vals(0u32, &mut vals);
assert_eq!(vals, &[] as &[u64]); assert_eq!(vals, &[] as &[u64]);

View File

@@ -1465,7 +1465,7 @@ mod tests {
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
assert_eq!(segment_reader.num_docs(), 8); assert_eq!(segment_reader.num_docs(), 8);
assert_eq!(segment_reader.max_doc(), 10); assert_eq!(segment_reader.max_doc(), 10);
let fast_field_reader = segment_reader.fast_fields().u64(id_field)?; let fast_field_reader = segment_reader.fast_fields().u64("id")?;
let in_order_alive_ids: Vec<u64> = segment_reader let in_order_alive_ids: Vec<u64> = segment_reader
.doc_ids_alive() .doc_ids_alive()
.map(|doc| fast_field_reader.get_val(doc)) .map(|doc| fast_field_reader.get_val(doc))
@@ -1526,7 +1526,7 @@ mod tests {
let segment_reader = searcher.segment_reader(0); let segment_reader = searcher.segment_reader(0);
assert_eq!(segment_reader.num_docs(), 8); assert_eq!(segment_reader.num_docs(), 8);
assert_eq!(segment_reader.max_doc(), 10); assert_eq!(segment_reader.max_doc(), 10);
let fast_field_reader = segment_reader.fast_fields().u64(id_field)?; let fast_field_reader = segment_reader.fast_fields().u64("id")?;
let in_order_alive_ids: Vec<u64> = segment_reader let in_order_alive_ids: Vec<u64> = segment_reader
.doc_ids_alive() .doc_ids_alive()
.map(|doc| fast_field_reader.get_val(doc)) .map(|doc| fast_field_reader.get_val(doc))
@@ -1778,7 +1778,7 @@ mod tests {
.segment_readers() .segment_readers()
.iter() .iter()
.flat_map(|segment_reader| { .flat_map(|segment_reader| {
let ff_reader = segment_reader.fast_fields().u64(id_field).unwrap(); let ff_reader = segment_reader.fast_fields().u64("id").unwrap();
segment_reader segment_reader
.doc_ids_alive() .doc_ids_alive()
.map(move |doc| ff_reader.get_val(doc)) .map(move |doc| ff_reader.get_val(doc))
@@ -1789,7 +1789,7 @@ mod tests {
.segment_readers() .segment_readers()
.iter() .iter()
.flat_map(|segment_reader| { .flat_map(|segment_reader| {
let ff_reader = segment_reader.fast_fields().u64(id_field).unwrap(); let ff_reader = segment_reader.fast_fields().u64("id").unwrap();
segment_reader segment_reader
.doc_ids_alive() .doc_ids_alive()
.map(move |doc| ff_reader.get_val(doc)) .map(move |doc| ff_reader.get_val(doc))
@@ -1804,7 +1804,7 @@ mod tests {
let mut all_ips = Vec::new(); let mut all_ips = Vec::new();
let mut num_ips = 0; let mut num_ips = 0;
for segment_reader in searcher.segment_readers().iter() { for segment_reader in searcher.segment_readers().iter() {
let ip_reader = segment_reader.fast_fields().ip_addrs(ips_field).unwrap(); let ip_reader = segment_reader.fast_fields().ip_addrs("ips").unwrap();
for doc in segment_reader.doc_ids_alive() { for doc in segment_reader.doc_ids_alive() {
let mut vals = vec![]; let mut vals = vec![];
ip_reader.get_vals(doc, &mut vals); ip_reader.get_vals(doc, &mut vals);
@@ -1851,7 +1851,7 @@ mod tests {
.segment_readers() .segment_readers()
.iter() .iter()
.map(|segment_reader| { .map(|segment_reader| {
let ff_reader = segment_reader.fast_fields().ip_addrs(ips_field).unwrap(); let ff_reader = segment_reader.fast_fields().ip_addrs("ips").unwrap();
ff_reader.get_index_reader().num_docs() as usize ff_reader.get_index_reader().num_docs() as usize
}) })
.sum(); .sum();
@@ -1863,7 +1863,7 @@ mod tests {
.segment_readers() .segment_readers()
.iter() .iter()
.flat_map(|segment_reader| { .flat_map(|segment_reader| {
let ff_reader = segment_reader.fast_fields().ip_addr(ip_field).unwrap(); let ff_reader = segment_reader.fast_fields().ip_addr("ip").unwrap();
segment_reader.doc_ids_alive().flat_map(move |doc| { segment_reader.doc_ids_alive().flat_map(move |doc| {
let val = ff_reader.get_val(doc); let val = ff_reader.get_val(doc);
if val == Ipv6Addr::from_u128(0) { if val == Ipv6Addr::from_u128(0) {
@@ -1902,7 +1902,7 @@ mod tests {
.segment_readers() .segment_readers()
.iter() .iter()
.flat_map(|segment_reader| { .flat_map(|segment_reader| {
let ff_reader = segment_reader.fast_fields().ip_addrs(ips_field).unwrap(); let ff_reader = segment_reader.fast_fields().ip_addrs("ips").unwrap();
segment_reader.doc_ids_alive().flat_map(move |doc| { segment_reader.doc_ids_alive().flat_map(move |doc| {
let mut vals = vec![]; let mut vals = vec![];
ff_reader.get_vals(doc, &mut vals); ff_reader.get_vals(doc, &mut vals);
@@ -1914,9 +1914,9 @@ mod tests {
// multivalue fast field tests // multivalue fast field tests
for segment_reader in searcher.segment_readers().iter() { for segment_reader in searcher.segment_readers().iter() {
let id_reader = segment_reader.fast_fields().u64(id_field).unwrap(); let id_reader = segment_reader.fast_fields().u64("id").unwrap();
let ff_reader = segment_reader.fast_fields().u64s(multi_numbers).unwrap(); let ff_reader = segment_reader.fast_fields().u64s("multi_numbers").unwrap();
let bool_ff_reader = segment_reader.fast_fields().bools(multi_bools).unwrap(); let bool_ff_reader = segment_reader.fast_fields().bools("multi_bools").unwrap();
for doc in segment_reader.doc_ids_alive() { for doc in segment_reader.doc_ids_alive() {
let mut vals = vec![]; let mut vals = vec![];
ff_reader.get_vals(doc, &mut vals); ff_reader.get_vals(doc, &mut vals);
@@ -2109,7 +2109,7 @@ mod tests {
// test facets // test facets
for segment_reader in searcher.segment_readers().iter() { for segment_reader in searcher.segment_readers().iter() {
let mut facet_reader = segment_reader.facet_reader(facet_field).unwrap(); let mut facet_reader = segment_reader.facet_reader(facet_field).unwrap();
let ff_reader = segment_reader.fast_fields().u64(id_field).unwrap(); let ff_reader = segment_reader.fast_fields().u64("id").unwrap();
for doc_id in segment_reader.doc_ids_alive() { for doc_id in segment_reader.doc_ids_alive() {
let mut facet_ords = Vec::new(); let mut facet_ords = Vec::new();
facet_reader.facet_ords(doc_id, &mut facet_ords); facet_reader.facet_ords(doc_id, &mut facet_ords);

View File

@@ -16,7 +16,7 @@ use crate::fastfield::{
MultiValueIndex, MultiValuedFastFieldReader, MultiValueIndex, MultiValuedFastFieldReader,
}; };
use crate::fieldnorm::{FieldNormReader, FieldNormReaders, FieldNormsSerializer, FieldNormsWriter}; use crate::fieldnorm::{FieldNormReader, FieldNormReaders, FieldNormsSerializer, FieldNormsWriter};
use crate::indexer::doc_id_mapping::{expect_field_id_for_sort_field, SegmentDocIdMapping}; use crate::indexer::doc_id_mapping::SegmentDocIdMapping;
use crate::indexer::sorted_doc_id_column::RemappedDocIdColumn; use crate::indexer::sorted_doc_id_column::RemappedDocIdColumn;
use crate::indexer::sorted_doc_id_multivalue_column::RemappedDocIdMultiValueColumn; use crate::indexer::sorted_doc_id_multivalue_column::RemappedDocIdMultiValueColumn;
use crate::indexer::SegmentSerializer; use crate::indexer::SegmentSerializer;
@@ -335,8 +335,10 @@ impl IndexMerger {
.readers .readers
.iter() .iter()
.map(|segment_reader| { .map(|segment_reader| {
let ff_reader: MultiValuedFastFieldReader<u128> = let ff_reader: MultiValuedFastFieldReader<u128> = segment_reader
segment_reader.fast_fields().u128s(field).expect( .fast_fields()
.u128s(self.schema.get_field_name(field))
.expect(
"Failed to find index for multivalued field. This is a bug in tantivy, \ "Failed to find index for multivalued field. This is a bug in tantivy, \
please report.", please report.",
); );
@@ -401,10 +403,13 @@ impl IndexMerger {
.readers .readers
.iter() .iter()
.map(|reader| { .map(|reader| {
let u128_reader: Arc<dyn Column<u128>> = reader.fast_fields().u128(field).expect( let u128_reader: Arc<dyn Column<u128>> = reader
"Failed to find a reader for single fast field. This is a tantivy bug and it \ .fast_fields()
should never happen.", .u128(self.schema.get_field_name(field))
); .expect(
"Failed to find a reader for single fast field. This is a tantivy bug and \
it should never happen.",
);
u128_reader u128_reader
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -431,7 +436,11 @@ impl IndexMerger {
fast_field_serializer: &mut CompositeFastFieldSerializer, fast_field_serializer: &mut CompositeFastFieldSerializer,
doc_id_mapping: &SegmentDocIdMapping, doc_id_mapping: &SegmentDocIdMapping,
) -> crate::Result<()> { ) -> crate::Result<()> {
let fast_field_accessor = RemappedDocIdColumn::new(&self.readers, doc_id_mapping, field); let fast_field_accessor = RemappedDocIdColumn::new(
&self.readers,
doc_id_mapping,
self.schema.get_field_name(field),
);
fast_field_serializer.create_auto_detect_u64_fast_field(field, fast_field_accessor)?; fast_field_serializer.create_auto_detect_u64_fast_field(field, fast_field_accessor)?;
Ok(()) Ok(())
@@ -464,8 +473,8 @@ impl IndexMerger {
reader: &SegmentReader, reader: &SegmentReader,
sort_by_field: &IndexSortByField, sort_by_field: &IndexSortByField,
) -> crate::Result<Arc<dyn Column>> { ) -> crate::Result<Arc<dyn Column>> {
let field_id = expect_field_id_for_sort_field(reader.schema(), sort_by_field)?; // for now expect fastfield, but not strictly required reader.schema().get_field(&sort_by_field.field)?;
let value_accessor = reader.fast_fields().u64_lenient(field_id)?; let value_accessor = reader.fast_fields().u64_lenient(&sort_by_field.field)?;
Ok(value_accessor) Ok(value_accessor)
} }
/// Collecting value_accessors into a vec to bind the lifetime. /// Collecting value_accessors into a vec to bind the lifetime.
@@ -569,7 +578,7 @@ impl IndexMerger {
.map(|reader| { .map(|reader| {
let u64s_reader: MultiValuedFastFieldReader<u64> = reader let u64s_reader: MultiValuedFastFieldReader<u64> = reader
.fast_fields() .fast_fields()
.typed_fast_field_multi_reader::<u64>(field) .typed_fast_field_multi_reader::<u64>(self.schema.get_field_name(field))
.expect( .expect(
"Failed to find index for multivalued field. This is a bug in tantivy, \ "Failed to find index for multivalued field. This is a bug in tantivy, \
please report.", please report.",
@@ -613,7 +622,7 @@ impl IndexMerger {
.map(|reader| { .map(|reader| {
let ff_reader: MultiValuedFastFieldReader<u64> = reader let ff_reader: MultiValuedFastFieldReader<u64> = reader
.fast_fields() .fast_fields()
.u64s(field) .u64s(self.schema.get_field_name(field))
.expect("Could not find multivalued u64 fast value reader."); .expect("Could not find multivalued u64 fast value reader.");
ff_reader ff_reader
}) })
@@ -684,8 +693,11 @@ impl IndexMerger {
self.write_multi_value_fast_field_idx(field, fast_field_serializer, doc_id_mapping)?; self.write_multi_value_fast_field_idx(field, fast_field_serializer, doc_id_mapping)?;
let fastfield_accessor = let fastfield_accessor = RemappedDocIdMultiValueColumn::new(
RemappedDocIdMultiValueColumn::new(&self.readers, doc_id_mapping, field); &self.readers,
doc_id_mapping,
self.schema.get_field_name(field),
);
fast_field_serializer.create_auto_detect_u64_fast_field_with_idx_and_codecs( fast_field_serializer.create_auto_detect_u64_fast_field_with_idx_and_codecs(
field, field,
fastfield_accessor, fastfield_accessor,
@@ -706,10 +718,13 @@ impl IndexMerger {
.readers .readers
.iter() .iter()
.map(|reader| { .map(|reader| {
let bytes_reader = reader.fast_fields().bytes(field).expect( let bytes_reader = reader
"Failed to find index for bytes field. This is a bug in tantivy, please \ .fast_fields()
report.", .bytes(self.schema.get_field_name(field))
); .expect(
"Failed to find index for bytes field. This is a bug in tantivy, please \
report.",
);
(reader, bytes_reader) (reader, bytes_reader)
}) })
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -1206,7 +1221,10 @@ mod tests {
{ {
let get_fast_vals = |terms: Vec<Term>| { let get_fast_vals = |terms: Vec<Term>| {
let query = BooleanQuery::new_multiterms_query(terms); let query = BooleanQuery::new_multiterms_query(terms);
searcher.search(&query, &FastFieldTestCollector::for_field(score_field)) searcher.search(
&query,
&FastFieldTestCollector::for_field("score".to_string()),
)
}; };
let get_fast_vals_bytes = |terms: Vec<Term>| { let get_fast_vals_bytes = |terms: Vec<Term>| {
let query = BooleanQuery::new_multiterms_query(terms); let query = BooleanQuery::new_multiterms_query(terms);
@@ -1244,7 +1262,7 @@ mod tests {
let mut index_writer = index.writer_for_tests()?; let mut index_writer = index.writer_for_tests()?;
let reader = index.reader().unwrap(); let reader = index.reader().unwrap();
let search_term = |searcher: &Searcher, term: Term| { let search_term = |searcher: &Searcher, term: Term| {
let collector = FastFieldTestCollector::for_field(score_field); let collector = FastFieldTestCollector::for_field("score".to_string());
let bytes_collector = BytesFastFieldTestCollector::for_field(bytes_score_field); let bytes_collector = BytesFastFieldTestCollector::for_field(bytes_score_field);
let term_query = TermQuery::new(term, IndexRecordOption::Basic); let term_query = TermQuery::new(term, IndexRecordOption::Basic);
searcher searcher
@@ -1366,7 +1384,7 @@ mod tests {
let score_field_reader = searcher let score_field_reader = searcher
.segment_reader(0) .segment_reader(0)
.fast_fields() .fast_fields()
.u64(score_field) .u64("score")
.unwrap(); .unwrap();
assert_eq!(score_field_reader.min_value(), 4000); assert_eq!(score_field_reader.min_value(), 4000);
assert_eq!(score_field_reader.max_value(), 7000); assert_eq!(score_field_reader.max_value(), 7000);
@@ -1374,7 +1392,7 @@ mod tests {
let score_field_reader = searcher let score_field_reader = searcher
.segment_reader(1) .segment_reader(1)
.fast_fields() .fast_fields()
.u64(score_field) .u64("score")
.unwrap(); .unwrap();
assert_eq!(score_field_reader.min_value(), 1); assert_eq!(score_field_reader.min_value(), 1);
assert_eq!(score_field_reader.max_value(), 3); assert_eq!(score_field_reader.max_value(), 3);
@@ -1420,7 +1438,7 @@ mod tests {
let score_field_reader = searcher let score_field_reader = searcher
.segment_reader(0) .segment_reader(0)
.fast_fields() .fast_fields()
.u64(score_field) .u64("score")
.unwrap(); .unwrap();
assert_eq!(score_field_reader.min_value(), 3); assert_eq!(score_field_reader.min_value(), 3);
assert_eq!(score_field_reader.max_value(), 7000); assert_eq!(score_field_reader.max_value(), 7000);
@@ -1467,7 +1485,7 @@ mod tests {
let score_field_reader = searcher let score_field_reader = searcher
.segment_reader(0) .segment_reader(0)
.fast_fields() .fast_fields()
.u64(score_field) .u64("score")
.unwrap(); .unwrap();
assert_eq!(score_field_reader.min_value(), 3); assert_eq!(score_field_reader.min_value(), 3);
assert_eq!(score_field_reader.max_value(), 7000); assert_eq!(score_field_reader.max_value(), 7000);
@@ -1514,7 +1532,7 @@ mod tests {
let score_field_reader = searcher let score_field_reader = searcher
.segment_reader(0) .segment_reader(0)
.fast_fields() .fast_fields()
.u64(score_field) .u64("score")
.unwrap(); .unwrap();
assert_eq!(score_field_reader.min_value(), 6000); assert_eq!(score_field_reader.min_value(), 6000);
assert_eq!(score_field_reader.max_value(), 7000); assert_eq!(score_field_reader.max_value(), 7000);
@@ -1836,7 +1854,7 @@ mod tests {
{ {
let segment = searcher.segment_reader(0u32); let segment = searcher.segment_reader(0u32);
let ff_reader = segment.fast_fields().u64s(int_field).unwrap(); let ff_reader = segment.fast_fields().u64s("intvals").unwrap();
ff_reader.get_vals(0, &mut vals); ff_reader.get_vals(0, &mut vals);
assert_eq!(&vals, &[1, 2]); assert_eq!(&vals, &[1, 2]);
@@ -1862,7 +1880,7 @@ mod tests {
{ {
let segment = searcher.segment_reader(1u32); let segment = searcher.segment_reader(1u32);
let ff_reader = segment.fast_fields().u64s(int_field).unwrap(); let ff_reader = segment.fast_fields().u64s("intvals").unwrap();
ff_reader.get_vals(0, &mut vals); ff_reader.get_vals(0, &mut vals);
assert_eq!(&vals, &[28, 27]); assert_eq!(&vals, &[28, 27]);
@@ -1872,7 +1890,7 @@ mod tests {
{ {
let segment = searcher.segment_reader(2u32); let segment = searcher.segment_reader(2u32);
let ff_reader = segment.fast_fields().u64s(int_field).unwrap(); let ff_reader = segment.fast_fields().u64s("intvals").unwrap();
ff_reader.get_vals(0, &mut vals); ff_reader.get_vals(0, &mut vals);
assert_eq!(&vals, &[20]); assert_eq!(&vals, &[20]);
} }
@@ -1889,7 +1907,7 @@ mod tests {
{ {
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment = searcher.segment_reader(0u32); let segment = searcher.segment_reader(0u32);
let ff_reader = segment.fast_fields().u64s(int_field).unwrap(); let ff_reader = segment.fast_fields().u64s("intvals").unwrap();
ff_reader.get_vals(0, &mut vals); ff_reader.get_vals(0, &mut vals);
assert_eq!(&vals, &[1, 2]); assert_eq!(&vals, &[1, 2]);

View File

@@ -185,7 +185,7 @@ mod tests {
let segment_reader = searcher.segment_readers().last().unwrap(); let segment_reader = searcher.segment_readers().last().unwrap();
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let fast_field = fast_fields.u64(int_field).unwrap(); let fast_field = fast_fields.u64("intval").unwrap();
assert_eq!(fast_field.get_val(5), 1u64); assert_eq!(fast_field.get_val(5), 1u64);
assert_eq!(fast_field.get_val(4), 2u64); assert_eq!(fast_field.get_val(4), 2u64);
assert_eq!(fast_field.get_val(3), 3u64); assert_eq!(fast_field.get_val(3), 3u64);
@@ -364,15 +364,13 @@ mod tests {
.unwrap(); .unwrap();
let int_field = index.schema().get_field("intval").unwrap(); let int_field = index.schema().get_field("intval").unwrap();
let multi_numbers = index.schema().get_field("multi_numbers").unwrap();
let bytes_field = index.schema().get_field("bytes").unwrap();
let reader = index.reader().unwrap(); let reader = index.reader().unwrap();
let searcher = reader.searcher(); let searcher = reader.searcher();
assert_eq!(searcher.segment_readers().len(), 1); assert_eq!(searcher.segment_readers().len(), 1);
let segment_reader = searcher.segment_readers().last().unwrap(); let segment_reader = searcher.segment_readers().last().unwrap();
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let fast_field = fast_fields.u64(int_field).unwrap(); let fast_field = fast_fields.u64("intval").unwrap();
assert_eq!(fast_field.get_val(0), 1u64); assert_eq!(fast_field.get_val(0), 1u64);
assert_eq!(fast_field.get_val(1), 2u64); assert_eq!(fast_field.get_val(1), 2u64);
assert_eq!(fast_field.get_val(2), 3u64); assert_eq!(fast_field.get_val(2), 3u64);
@@ -386,7 +384,7 @@ mod tests {
vals vals
}; };
let fast_fields = segment_reader.fast_fields(); let fast_fields = segment_reader.fast_fields();
let fast_field = fast_fields.u64s(multi_numbers).unwrap(); let fast_field = fast_fields.u64s("multi_numbers").unwrap();
assert_eq!(&get_vals(&fast_field, 0), &[] as &[u64]); assert_eq!(&get_vals(&fast_field, 0), &[] as &[u64]);
assert_eq!(&get_vals(&fast_field, 1), &[2, 3]); assert_eq!(&get_vals(&fast_field, 1), &[2, 3]);
assert_eq!(&get_vals(&fast_field, 2), &[3, 4]); assert_eq!(&get_vals(&fast_field, 2), &[3, 4]);
@@ -394,7 +392,7 @@ mod tests {
assert_eq!(&get_vals(&fast_field, 4), &[20]); assert_eq!(&get_vals(&fast_field, 4), &[20]);
assert_eq!(&get_vals(&fast_field, 5), &[1001, 1002]); assert_eq!(&get_vals(&fast_field, 5), &[1001, 1002]);
let fast_field = fast_fields.bytes(bytes_field).unwrap(); let fast_field = fast_fields.bytes("bytes").unwrap();
assert_eq!(fast_field.get_bytes(0), &[] as &[u8]); assert_eq!(fast_field.get_bytes(0), &[] as &[u8]);
assert_eq!(fast_field.get_bytes(2), &[1, 2, 3]); assert_eq!(fast_field.get_bytes(2), &[1, 2, 3]);
assert_eq!(fast_field.get_bytes(5), &[5, 5]); assert_eq!(fast_field.get_bytes(5), &[5, 5]);
@@ -527,7 +525,6 @@ mod bench_sorted_index_merge {
order: Order::Desc, order: Order::Desc,
}; };
let index = create_index(Some(sort_by_field.clone())); let index = create_index(Some(sort_by_field.clone()));
let field = index.schema().get_field("intval").unwrap();
let segments = index.searchable_segments().unwrap(); let segments = index.searchable_segments().unwrap();
let merger: IndexMerger = let merger: IndexMerger =
IndexMerger::open(index.schema(), index.settings().clone(), &segments[..])?; IndexMerger::open(index.schema(), index.settings().clone(), &segments[..])?;
@@ -535,8 +532,10 @@ mod bench_sorted_index_merge {
b.iter(|| { b.iter(|| {
let sorted_doc_ids = doc_id_mapping.iter_old_doc_addrs().map(|doc_addr| { let sorted_doc_ids = doc_id_mapping.iter_old_doc_addrs().map(|doc_addr| {
let reader = &merger.readers[doc_addr.segment_ord as usize]; let reader = &merger.readers[doc_addr.segment_ord as usize];
let u64_reader: Arc<dyn Column<u64>> = let u64_reader: Arc<dyn Column<u64>> = reader
reader.fast_fields().typed_fast_field_reader(field).expect( .fast_fields()
.typed_fast_field_reader("intval")
.expect(
"Failed to find a reader for single fast field. This is a tantivy bug and \ "Failed to find a reader for single fast field. This is a tantivy bug and \
it should never happen.", it should never happen.",
); );

View File

@@ -4,7 +4,6 @@ use fastfield_codecs::Column;
use itertools::Itertools; use itertools::Itertools;
use crate::indexer::doc_id_mapping::SegmentDocIdMapping; use crate::indexer::doc_id_mapping::SegmentDocIdMapping;
use crate::schema::Field;
use crate::SegmentReader; use crate::SegmentReader;
pub(crate) struct RemappedDocIdColumn<'a> { pub(crate) struct RemappedDocIdColumn<'a> {
@@ -41,7 +40,7 @@ impl<'a> RemappedDocIdColumn<'a> {
pub(crate) fn new( pub(crate) fn new(
readers: &'a [SegmentReader], readers: &'a [SegmentReader],
doc_id_mapping: &'a SegmentDocIdMapping, doc_id_mapping: &'a SegmentDocIdMapping,
field: Field, field: &str,
) -> Self { ) -> Self {
let (min_value, max_value) = readers let (min_value, max_value) = readers
.iter() .iter()

View File

@@ -5,7 +5,6 @@ use fastfield_codecs::Column;
use super::flat_map_with_buffer::FlatMapWithBufferIter; use super::flat_map_with_buffer::FlatMapWithBufferIter;
use crate::fastfield::{MultiValueIndex, MultiValuedFastFieldReader}; use crate::fastfield::{MultiValueIndex, MultiValuedFastFieldReader};
use crate::indexer::doc_id_mapping::SegmentDocIdMapping; use crate::indexer::doc_id_mapping::SegmentDocIdMapping;
use crate::schema::Field;
use crate::{DocAddress, SegmentReader}; use crate::{DocAddress, SegmentReader};
pub(crate) struct RemappedDocIdMultiValueColumn<'a> { pub(crate) struct RemappedDocIdMultiValueColumn<'a> {
@@ -20,7 +19,7 @@ impl<'a> RemappedDocIdMultiValueColumn<'a> {
pub(crate) fn new( pub(crate) fn new(
readers: &'a [SegmentReader], readers: &'a [SegmentReader],
doc_id_mapping: &'a SegmentDocIdMapping, doc_id_mapping: &'a SegmentDocIdMapping,
field: Field, field: &str,
) -> Self { ) -> Self {
// Our values are bitpacked and we need to know what should be // Our values are bitpacked and we need to know what should be
// our bitwidth and our minimum value before serializing any values. // our bitwidth and our minimum value before serializing any values.

View File

@@ -995,8 +995,8 @@ pub mod tests {
let fast_field_unsigned = schema_builder.add_u64_field("unsigned", FAST); let fast_field_unsigned = schema_builder.add_u64_field("unsigned", FAST);
let fast_field_signed = schema_builder.add_i64_field("signed", FAST); let fast_field_signed = schema_builder.add_i64_field("signed", FAST);
let fast_field_float = schema_builder.add_f64_field("float", FAST); let fast_field_float = schema_builder.add_f64_field("float", FAST);
let text_field = schema_builder.add_text_field("text", TEXT); schema_builder.add_text_field("text", TEXT);
let stored_int_field = schema_builder.add_u64_field("stored_int", STORED); schema_builder.add_u64_field("stored_int", STORED);
let schema = schema_builder.build(); let schema = schema_builder.build();
let index = Index::create_in_ram(schema); let index = Index::create_in_ram(schema);
@@ -1011,37 +1011,37 @@ pub mod tests {
let searcher = reader.searcher(); let searcher = reader.searcher();
let segment_reader: &SegmentReader = searcher.segment_reader(0); let segment_reader: &SegmentReader = searcher.segment_reader(0);
{ {
let fast_field_reader_res = segment_reader.fast_fields().u64(text_field); let fast_field_reader_res = segment_reader.fast_fields().u64("text");
assert!(fast_field_reader_res.is_err()); assert!(fast_field_reader_res.is_err());
} }
{ {
let fast_field_reader_opt = segment_reader.fast_fields().u64(stored_int_field); let fast_field_reader_opt = segment_reader.fast_fields().u64("stored_int");
assert!(fast_field_reader_opt.is_err()); assert!(fast_field_reader_opt.is_err());
} }
{ {
let fast_field_reader_opt = segment_reader.fast_fields().u64(fast_field_signed); let fast_field_reader_opt = segment_reader.fast_fields().u64("signed");
assert!(fast_field_reader_opt.is_err()); assert!(fast_field_reader_opt.is_err());
} }
{ {
let fast_field_reader_opt = segment_reader.fast_fields().u64(fast_field_float); let fast_field_reader_opt = segment_reader.fast_fields().u64("float");
assert!(fast_field_reader_opt.is_err()); assert!(fast_field_reader_opt.is_err());
} }
{ {
let fast_field_reader_opt = segment_reader.fast_fields().u64(fast_field_unsigned); let fast_field_reader_opt = segment_reader.fast_fields().u64("unsigned");
assert!(fast_field_reader_opt.is_ok()); assert!(fast_field_reader_opt.is_ok());
let fast_field_reader = fast_field_reader_opt.unwrap(); let fast_field_reader = fast_field_reader_opt.unwrap();
assert_eq!(fast_field_reader.get_val(0), 4u64) assert_eq!(fast_field_reader.get_val(0), 4u64)
} }
{ {
let fast_field_reader_res = segment_reader.fast_fields().i64(fast_field_signed); let fast_field_reader_res = segment_reader.fast_fields().i64("signed");
assert!(fast_field_reader_res.is_ok()); assert!(fast_field_reader_res.is_ok());
let fast_field_reader = fast_field_reader_res.unwrap(); let fast_field_reader = fast_field_reader_res.unwrap();
assert_eq!(fast_field_reader.get_val(0), 4i64) assert_eq!(fast_field_reader.get_val(0), 4i64)
} }
{ {
let fast_field_reader_res = segment_reader.fast_fields().f64(fast_field_float); let fast_field_reader_res = segment_reader.fast_fields().f64("float");
assert!(fast_field_reader_res.is_ok()); assert!(fast_field_reader_res.is_ok());
let fast_field_reader = fast_field_reader_res.unwrap(); let fast_field_reader = fast_field_reader_res.unwrap();
assert_eq!(fast_field_reader.get_val(0), 4f64) assert_eq!(fast_field_reader.get_val(0), 4f64)

View File

@@ -10,7 +10,7 @@ pub enum LogicalLiteral {
Term(Term), Term(Term),
Phrase(Vec<(usize, Term)>, u32), Phrase(Vec<(usize, Term)>, u32),
Range { Range {
field: Field, field: String,
value_type: Type, value_type: Type,
lower: Bound<Term>, lower: Bound<Term>,
upper: Bound<Term>, upper: Bound<Term>,

View File

@@ -672,7 +672,7 @@ impl QueryParser {
let field_entry = self.schema.get_field_entry(field); let field_entry = self.schema.get_field_entry(field);
let value_type = field_entry.field_type().value_type(); let value_type = field_entry.field_type().value_type();
let logical_ast = LogicalAst::Leaf(Box::new(LogicalLiteral::Range { let logical_ast = LogicalAst::Leaf(Box::new(LogicalLiteral::Range {
field, field: self.schema.get_field_name(field).to_string(),
value_type, value_type,
lower: self.resolve_bound(field, json_path, &lower)?, lower: self.resolve_bound(field, json_path, &lower)?,
upper: self.resolve_bound(field, json_path, &upper)?, upper: self.resolve_bound(field, json_path, &upper)?,
@@ -964,7 +964,7 @@ mod test {
let query = make_query_parser().parse_query("title:[A TO B]").unwrap(); let query = make_query_parser().parse_query("title:[A TO B]").unwrap();
assert_eq!( assert_eq!(
format!("{:?}", query), format!("{:?}", query),
"RangeQuery { field: Field(0), value_type: Str, left_bound: Included([97]), \ "RangeQuery { field: \"title\", value_type: Str, left_bound: Included([97]), \
right_bound: Included([98]) }" right_bound: Included([98]) }"
); );
} }

View File

@@ -67,7 +67,7 @@ pub(crate) fn map_bound<TFrom, TTo, Transform: Fn(&TFrom) -> TTo>(
/// ///
/// let reader = index.reader()?; /// let reader = index.reader()?;
/// let searcher = reader.searcher(); /// let searcher = reader.searcher();
/// let docs_in_the_sixties = RangeQuery::new_u64(year_field, 1960..1970); /// let docs_in_the_sixties = RangeQuery::new_u64("year".to_string(), 1960..1970);
/// let num_60s_books = searcher.search(&docs_in_the_sixties, &Count)?; /// let num_60s_books = searcher.search(&docs_in_the_sixties, &Count)?;
/// assert_eq!(num_60s_books, 2285); /// assert_eq!(num_60s_books, 2285);
/// Ok(()) /// Ok(())
@@ -76,7 +76,7 @@ pub(crate) fn map_bound<TFrom, TTo, Transform: Fn(&TFrom) -> TTo>(
/// ``` /// ```
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct RangeQuery { pub struct RangeQuery {
field: Field, field: String,
value_type: Type, value_type: Type,
left_bound: Bound<Vec<u8>>, left_bound: Bound<Vec<u8>>,
right_bound: Bound<Vec<u8>>, right_bound: Bound<Vec<u8>>,
@@ -88,15 +88,12 @@ impl RangeQuery {
/// If the value type is not correct, something may go terribly wrong when /// If the value type is not correct, something may go terribly wrong when
/// the `Weight` object is created. /// the `Weight` object is created.
pub fn new_term_bounds( pub fn new_term_bounds(
field: Field, field: String,
value_type: Type, value_type: Type,
left_bound: &Bound<Term>, left_bound: &Bound<Term>,
right_bound: &Bound<Term>, right_bound: &Bound<Term>,
) -> RangeQuery { ) -> RangeQuery {
let verify_and_unwrap_term = |val: &Term| { let verify_and_unwrap_term = |val: &Term| val.value_bytes().to_owned();
assert_eq!(field, val.field());
val.value_bytes().to_owned()
};
RangeQuery { RangeQuery {
field, field,
value_type, value_type,
@@ -109,7 +106,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `i64`, tantivy /// If the field is not of the type `i64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_i64(field: Field, range: Range<i64>) -> RangeQuery { pub fn new_i64(field: String, range: Range<i64>) -> RangeQuery {
RangeQuery::new_i64_bounds( RangeQuery::new_i64_bounds(
field, field,
Bound::Included(range.start), Bound::Included(range.start),
@@ -125,11 +122,15 @@ impl RangeQuery {
/// If the field is not of the type `i64`, tantivy /// If the field is not of the type `i64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_i64_bounds( pub fn new_i64_bounds(
field: Field, field: String,
left_bound: Bound<i64>, left_bound: Bound<i64>,
right_bound: Bound<i64>, right_bound: Bound<i64>,
) -> RangeQuery { ) -> RangeQuery {
let make_term_val = |val: &i64| Term::from_field_i64(field, *val).value_bytes().to_owned(); let make_term_val = |val: &i64| {
Term::from_field_i64(Field::from_field_id(0), *val)
.value_bytes()
.to_owned()
};
RangeQuery { RangeQuery {
field, field,
value_type: Type::I64, value_type: Type::I64,
@@ -142,7 +143,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `f64`, tantivy /// If the field is not of the type `f64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_f64(field: Field, range: Range<f64>) -> RangeQuery { pub fn new_f64(field: String, range: Range<f64>) -> RangeQuery {
RangeQuery::new_f64_bounds( RangeQuery::new_f64_bounds(
field, field,
Bound::Included(range.start), Bound::Included(range.start),
@@ -158,11 +159,15 @@ impl RangeQuery {
/// If the field is not of the type `f64`, tantivy /// If the field is not of the type `f64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_f64_bounds( pub fn new_f64_bounds(
field: Field, field: String,
left_bound: Bound<f64>, left_bound: Bound<f64>,
right_bound: Bound<f64>, right_bound: Bound<f64>,
) -> RangeQuery { ) -> RangeQuery {
let make_term_val = |val: &f64| Term::from_field_f64(field, *val).value_bytes().to_owned(); let make_term_val = |val: &f64| {
Term::from_field_f64(Field::from_field_id(0), *val)
.value_bytes()
.to_owned()
};
RangeQuery { RangeQuery {
field, field,
value_type: Type::F64, value_type: Type::F64,
@@ -179,11 +184,15 @@ impl RangeQuery {
/// If the field is not of the type `u64`, tantivy /// If the field is not of the type `u64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_u64_bounds( pub fn new_u64_bounds(
field: Field, field: String,
left_bound: Bound<u64>, left_bound: Bound<u64>,
right_bound: Bound<u64>, right_bound: Bound<u64>,
) -> RangeQuery { ) -> RangeQuery {
let make_term_val = |val: &u64| Term::from_field_u64(field, *val).value_bytes().to_owned(); let make_term_val = |val: &u64| {
Term::from_field_u64(Field::from_field_id(0), *val)
.value_bytes()
.to_owned()
};
RangeQuery { RangeQuery {
field, field,
value_type: Type::U64, value_type: Type::U64,
@@ -196,7 +205,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `u64`, tantivy /// If the field is not of the type `u64`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_u64(field: Field, range: Range<u64>) -> RangeQuery { pub fn new_u64(field: String, range: Range<u64>) -> RangeQuery {
RangeQuery::new_u64_bounds( RangeQuery::new_u64_bounds(
field, field,
Bound::Included(range.start), Bound::Included(range.start),
@@ -212,12 +221,15 @@ impl RangeQuery {
/// If the field is not of the type `date`, tantivy /// If the field is not of the type `date`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_date_bounds( pub fn new_date_bounds(
field: Field, field: String,
left_bound: Bound<DateTime>, left_bound: Bound<DateTime>,
right_bound: Bound<DateTime>, right_bound: Bound<DateTime>,
) -> RangeQuery { ) -> RangeQuery {
let make_term_val = let make_term_val = |val: &DateTime| {
|val: &DateTime| Term::from_field_date(field, *val).value_bytes().to_owned(); Term::from_field_date(Field::from_field_id(0), *val)
.value_bytes()
.to_owned()
};
RangeQuery { RangeQuery {
field, field,
value_type: Type::Date, value_type: Type::Date,
@@ -230,7 +242,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `date`, tantivy /// If the field is not of the type `date`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_date(field: Field, range: Range<DateTime>) -> RangeQuery { pub fn new_date(field: String, range: Range<DateTime>) -> RangeQuery {
RangeQuery::new_date_bounds( RangeQuery::new_date_bounds(
field, field,
Bound::Included(range.start), Bound::Included(range.start),
@@ -245,7 +257,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `Str`, tantivy /// If the field is not of the type `Str`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_str_bounds(field: Field, left: Bound<&str>, right: Bound<&str>) -> RangeQuery { pub fn new_str_bounds(field: String, left: Bound<&str>, right: Bound<&str>) -> RangeQuery {
let make_term_val = |val: &&str| val.as_bytes().to_vec(); let make_term_val = |val: &&str| val.as_bytes().to_vec();
RangeQuery { RangeQuery {
field, field,
@@ -259,7 +271,7 @@ impl RangeQuery {
/// ///
/// If the field is not of the type `Str`, tantivy /// If the field is not of the type `Str`, tantivy
/// will panic when the `Weight` object is created. /// will panic when the `Weight` object is created.
pub fn new_str(field: Field, range: Range<&str>) -> RangeQuery { pub fn new_str(field: String, range: Range<&str>) -> RangeQuery {
RangeQuery::new_str_bounds( RangeQuery::new_str_bounds(
field, field,
Bound::Included(range.start), Bound::Included(range.start),
@@ -268,22 +280,8 @@ impl RangeQuery {
} }
/// Field to search over /// Field to search over
pub fn field(&self) -> Field { pub fn field(&self) -> &str {
self.field &self.field
}
/// Lower bound of range
pub fn left_bound(&self) -> Bound<Term> {
map_bound(&self.left_bound, &|bytes| {
Term::from_field_bytes(self.field, bytes)
})
}
/// Upper bound of range
pub fn right_bound(&self) -> Bound<Term> {
map_bound(&self.right_bound, &|bytes| {
Term::from_field_bytes(self.field, bytes)
})
} }
} }
@@ -307,7 +305,9 @@ pub(crate) fn maps_to_u64_fastfield(typ: Type) -> bool {
impl Query for RangeQuery { impl Query for RangeQuery {
fn weight(&self, enable_scoring: EnableScoring<'_>) -> crate::Result<Box<dyn Weight>> { fn weight(&self, enable_scoring: EnableScoring<'_>) -> crate::Result<Box<dyn Weight>> {
let schema = enable_scoring.schema(); let schema = enable_scoring.schema();
let field_type = schema.get_field_entry(self.field).field_type(); let field_type = schema
.get_field_entry(schema.get_field(&self.field)?)
.field_type();
let value_type = field_type.value_type(); let value_type = field_type.value_type();
if value_type != self.value_type { if value_type != self.value_type {
let err_msg = format!( let err_msg = format!(
@@ -320,7 +320,7 @@ impl Query for RangeQuery {
if field_type.is_fast() && is_type_valid_for_fastfield_range_query(self.value_type) { if field_type.is_fast() && is_type_valid_for_fastfield_range_query(self.value_type) {
if field_type.is_ip_addr() { if field_type.is_ip_addr() {
Ok(Box::new(IPFastFieldRangeWeight::new( Ok(Box::new(IPFastFieldRangeWeight::new(
self.field, self.field.to_string(),
&self.left_bound, &self.left_bound,
&self.right_bound, &self.right_bound,
))) )))
@@ -335,14 +335,14 @@ impl Query for RangeQuery {
let left_bound = map_bound(&self.left_bound, &parse_from_bytes); let left_bound = map_bound(&self.left_bound, &parse_from_bytes);
let right_bound = map_bound(&self.right_bound, &parse_from_bytes); let right_bound = map_bound(&self.right_bound, &parse_from_bytes);
Ok(Box::new(FastFieldRangeWeight::new( Ok(Box::new(FastFieldRangeWeight::new(
self.field, self.field.to_string(),
left_bound, left_bound,
right_bound, right_bound,
))) )))
} }
} else { } else {
Ok(Box::new(RangeWeight { Ok(Box::new(RangeWeight {
field: self.field, field: self.field.to_string(),
left_bound: self.left_bound.clone(), left_bound: self.left_bound.clone(),
right_bound: self.right_bound.clone(), right_bound: self.right_bound.clone(),
})) }))
@@ -351,7 +351,7 @@ impl Query for RangeQuery {
} }
pub struct RangeWeight { pub struct RangeWeight {
field: Field, field: String,
left_bound: Bound<Vec<u8>>, left_bound: Bound<Vec<u8>>,
right_bound: Bound<Vec<u8>>, right_bound: Bound<Vec<u8>>,
} }
@@ -379,7 +379,7 @@ impl Weight for RangeWeight {
let max_doc = reader.max_doc(); let max_doc = reader.max_doc();
let mut doc_bitset = BitSet::with_max_value(max_doc); let mut doc_bitset = BitSet::with_max_value(max_doc);
let inverted_index = reader.inverted_index(self.field)?; let inverted_index = reader.inverted_index(reader.schema().get_field(&self.field)?)?;
let term_dict = inverted_index.terms(); let term_dict = inverted_index.terms();
let mut term_range = self.term_range(term_dict)?; let mut term_range = self.term_range(term_dict)?;
while term_range.advance() { while term_range.advance() {
@@ -443,7 +443,7 @@ mod tests {
let reader = index.reader()?; let reader = index.reader()?;
let searcher = reader.searcher(); let searcher = reader.searcher();
let docs_in_the_sixties = RangeQuery::new_u64(year_field, 1960u64..1970u64); let docs_in_the_sixties = RangeQuery::new_u64("year".to_string(), 1960u64..1970u64);
// ... or `1960..=1969` if inclusive range is enabled. // ... or `1960..=1969` if inclusive range is enabled.
let count = searcher.search(&docs_in_the_sixties, &Count)?; let count = searcher.search(&docs_in_the_sixties, &Count)?;
@@ -481,10 +481,13 @@ mod tests {
let count_multiples = let count_multiples =
|range_query: RangeQuery| searcher.search(&range_query, &Count).unwrap(); |range_query: RangeQuery| searcher.search(&range_query, &Count).unwrap();
assert_eq!(count_multiples(RangeQuery::new_i64(int_field, 10..11)), 9); assert_eq!(
count_multiples(RangeQuery::new_i64("intfield".to_string(), 10..11)),
9
);
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_i64_bounds( count_multiples(RangeQuery::new_i64_bounds(
int_field, "intfield".to_string(),
Bound::Included(10), Bound::Included(10),
Bound::Included(11) Bound::Included(11)
)), )),
@@ -492,7 +495,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_i64_bounds( count_multiples(RangeQuery::new_i64_bounds(
int_field, "intfield".to_string(),
Bound::Excluded(9), Bound::Excluded(9),
Bound::Included(10) Bound::Included(10)
)), )),
@@ -500,7 +503,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_i64_bounds( count_multiples(RangeQuery::new_i64_bounds(
int_field, "intfield".to_string(),
Bound::Included(9), Bound::Included(9),
Bound::Unbounded Bound::Unbounded
)), )),
@@ -540,12 +543,12 @@ mod tests {
|range_query: RangeQuery| searcher.search(&range_query, &Count).unwrap(); |range_query: RangeQuery| searcher.search(&range_query, &Count).unwrap();
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_f64(float_field, 10.0..11.0)), count_multiples(RangeQuery::new_f64("floatfield".to_string(), 10.0..11.0)),
9 9
); );
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_f64_bounds( count_multiples(RangeQuery::new_f64_bounds(
float_field, "floatfield".to_string(),
Bound::Included(10.0), Bound::Included(10.0),
Bound::Included(11.0) Bound::Included(11.0)
)), )),
@@ -553,7 +556,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_f64_bounds( count_multiples(RangeQuery::new_f64_bounds(
float_field, "floatfield".to_string(),
Bound::Excluded(9.0), Bound::Excluded(9.0),
Bound::Included(10.0) Bound::Included(10.0)
)), )),
@@ -561,7 +564,7 @@ mod tests {
); );
assert_eq!( assert_eq!(
count_multiples(RangeQuery::new_f64_bounds( count_multiples(RangeQuery::new_f64_bounds(
float_field, "floatfield".to_string(),
Bound::Included(9.0), Bound::Included(9.0),
Bound::Unbounded Bound::Unbounded
)), )),

View File

@@ -11,18 +11,18 @@ use fastfield_codecs::MonotonicallyMappableToU128;
use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet}; use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet};
use super::range_query::map_bound; use super::range_query::map_bound;
use crate::query::{ConstScorer, Explanation, Scorer, Weight}; use crate::query::{ConstScorer, Explanation, Scorer, Weight};
use crate::schema::{Cardinality, Field}; use crate::schema::Cardinality;
use crate::{DocId, DocSet, Score, SegmentReader, TantivyError}; use crate::{DocId, DocSet, Score, SegmentReader, TantivyError};
/// `IPFastFieldRangeWeight` uses the ip address fast field to execute range queries. /// `IPFastFieldRangeWeight` uses the ip address fast field to execute range queries.
pub struct IPFastFieldRangeWeight { pub struct IPFastFieldRangeWeight {
field: Field, field: String,
left_bound: Bound<Ipv6Addr>, left_bound: Bound<Ipv6Addr>,
right_bound: Bound<Ipv6Addr>, right_bound: Bound<Ipv6Addr>,
} }
impl IPFastFieldRangeWeight { impl IPFastFieldRangeWeight {
pub fn new(field: Field, left_bound: &Bound<Vec<u8>>, right_bound: &Bound<Vec<u8>>) -> Self { pub fn new(field: String, left_bound: &Bound<Vec<u8>>, right_bound: &Bound<Vec<u8>>) -> Self {
let parse_ip_from_bytes = |data: &Vec<u8>| { let parse_ip_from_bytes = |data: &Vec<u8>| {
let ip_u128: u128 = let ip_u128: u128 =
u128::from_be(BinarySerializable::deserialize(&mut &data[..]).unwrap()); u128::from_be(BinarySerializable::deserialize(&mut &data[..]).unwrap());
@@ -40,10 +40,13 @@ impl IPFastFieldRangeWeight {
impl Weight for IPFastFieldRangeWeight { impl Weight for IPFastFieldRangeWeight {
fn scorer(&self, reader: &SegmentReader, boost: Score) -> crate::Result<Box<dyn Scorer>> { fn scorer(&self, reader: &SegmentReader, boost: Score) -> crate::Result<Box<dyn Scorer>> {
let field_type = reader.schema().get_field_entry(self.field).field_type(); let field_type = reader
.schema()
.get_field_entry(reader.schema().get_field(&self.field)?)
.field_type();
match field_type.fastfield_cardinality().unwrap() { match field_type.fastfield_cardinality().unwrap() {
Cardinality::SingleValue => { Cardinality::SingleValue => {
let ip_addr_fast_field = reader.fast_fields().ip_addr(self.field)?; let ip_addr_fast_field = reader.fast_fields().ip_addr(&self.field)?;
let value_range = bound_to_value_range( let value_range = bound_to_value_range(
&self.left_bound, &self.left_bound,
&self.right_bound, &self.right_bound,
@@ -57,7 +60,7 @@ impl Weight for IPFastFieldRangeWeight {
Ok(Box::new(ConstScorer::new(docset, boost))) Ok(Box::new(ConstScorer::new(docset, boost)))
} }
Cardinality::MultiValues => { Cardinality::MultiValues => {
let ip_addr_fast_field = reader.fast_fields().ip_addrs(self.field)?; let ip_addr_fast_field = reader.fast_fields().ip_addrs(&self.field)?;
let value_range = bound_to_value_range( let value_range = bound_to_value_range(
&self.left_bound, &self.left_bound,
&self.right_bound, &self.right_bound,

View File

@@ -9,18 +9,18 @@ use fastfield_codecs::MonotonicallyMappableToU64;
use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet}; use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet};
use super::range_query::map_bound; use super::range_query::map_bound;
use crate::query::{ConstScorer, Explanation, Scorer, Weight}; use crate::query::{ConstScorer, Explanation, Scorer, Weight};
use crate::schema::{Cardinality, Field}; use crate::schema::Cardinality;
use crate::{DocId, DocSet, Score, SegmentReader, TantivyError}; use crate::{DocId, DocSet, Score, SegmentReader, TantivyError};
/// `FastFieldRangeWeight` uses the fast field to execute range queries. /// `FastFieldRangeWeight` uses the fast field to execute range queries.
pub struct FastFieldRangeWeight { pub struct FastFieldRangeWeight {
field: Field, field: String,
left_bound: Bound<u64>, left_bound: Bound<u64>,
right_bound: Bound<u64>, right_bound: Bound<u64>,
} }
impl FastFieldRangeWeight { impl FastFieldRangeWeight {
pub fn new(field: Field, left_bound: Bound<u64>, right_bound: Bound<u64>) -> Self { pub fn new(field: String, left_bound: Bound<u64>, right_bound: Bound<u64>) -> Self {
let left_bound = map_bound(&left_bound, &|val| *val); let left_bound = map_bound(&left_bound, &|val| *val);
let right_bound = map_bound(&right_bound, &|val| *val); let right_bound = map_bound(&right_bound, &|val| *val);
Self { Self {
@@ -33,10 +33,13 @@ impl FastFieldRangeWeight {
impl Weight for FastFieldRangeWeight { impl Weight for FastFieldRangeWeight {
fn scorer(&self, reader: &SegmentReader, boost: Score) -> crate::Result<Box<dyn Scorer>> { fn scorer(&self, reader: &SegmentReader, boost: Score) -> crate::Result<Box<dyn Scorer>> {
let field_type = reader.schema().get_field_entry(self.field).field_type(); let field_type = reader
.schema()
.get_field_entry(reader.schema().get_field(&self.field)?)
.field_type();
match field_type.fastfield_cardinality().unwrap() { match field_type.fastfield_cardinality().unwrap() {
Cardinality::SingleValue => { Cardinality::SingleValue => {
let fast_field = reader.fast_fields().u64_lenient(self.field)?; let fast_field = reader.fast_fields().u64_lenient(&self.field)?;
let value_range = bound_to_value_range( let value_range = bound_to_value_range(
&self.left_bound, &self.left_bound,
&self.right_bound, &self.right_bound,
@@ -48,7 +51,7 @@ impl Weight for FastFieldRangeWeight {
Ok(Box::new(ConstScorer::new(docset, boost))) Ok(Box::new(ConstScorer::new(docset, boost)))
} }
Cardinality::MultiValues => { Cardinality::MultiValues => {
let fast_field = reader.fast_fields().u64s_lenient(self.field)?; let fast_field = reader.fast_fields().u64s_lenient(&self.field)?;
let value_range = bound_to_value_range( let value_range = bound_to_value_range(
&self.left_bound, &self.left_bound,
&self.right_bound, &self.right_bound,

View File

@@ -11,6 +11,7 @@ use super::ip_options::IpAddrOptions;
use super::*; use super::*;
use crate::schema::bytes_options::BytesOptions; use crate::schema::bytes_options::BytesOptions;
use crate::schema::field_type::ValueParsingError; use crate::schema::field_type::ValueParsingError;
use crate::TantivyError;
/// Tantivy has a very strict schema. /// Tantivy has a very strict schema.
/// You need to specify in advance whether a field is indexed or not, /// You need to specify in advance whether a field is indexed or not,
@@ -308,8 +309,12 @@ impl Schema {
} }
/// Returns the field option associated with a given name. /// Returns the field option associated with a given name.
pub fn get_field(&self, field_name: &str) -> Option<Field> { pub fn get_field(&self, field_name: &str) -> crate::Result<Field> {
self.0.fields_map.get(field_name).cloned() self.0
.fields_map
.get(field_name)
.cloned()
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))
} }
/// Create document from a named doc. /// Create document from a named doc.
@@ -319,7 +324,7 @@ impl Schema {
) -> Result<Document, DocParsingError> { ) -> Result<Document, DocParsingError> {
let mut document = Document::new(); let mut document = Document::new();
for (field_name, values) in named_doc.0 { for (field_name, values) in named_doc.0 {
if let Some(field) = self.get_field(&field_name) { if let Ok(field) = self.get_field(&field_name) {
for value in values { for value in values {
document.add_field_value(field, value); document.add_field_value(field, value);
} }
@@ -360,7 +365,7 @@ impl Schema {
) -> Result<Document, DocParsingError> { ) -> Result<Document, DocParsingError> {
let mut doc = Document::default(); let mut doc = Document::default();
for (field_name, json_value) in json_obj { for (field_name, json_value) in json_obj {
if let Some(field) = self.get_field(&field_name) { if let Ok(field) = self.get_field(&field_name) {
let field_entry = self.get_field_entry(field); let field_entry = self.get_field_entry(field);
let field_type = field_entry.field_type(); let field_type = field_entry.field_type();
match json_value { match json_value {