mirror of
https://github.com/quickwit-oss/tantivy.git
synced 2025-12-28 04:52:55 +00:00
Compare commits
2 Commits
check_bug
...
columnar-m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
937485321a | ||
|
|
e3be14e7d8 |
@@ -14,7 +14,7 @@ use fastfield_codecs::Column;
|
||||
// Importing tantivy...
|
||||
use tantivy::collector::{Collector, SegmentCollector};
|
||||
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};
|
||||
|
||||
#[derive(Default)]
|
||||
@@ -52,11 +52,11 @@ impl Stats {
|
||||
}
|
||||
|
||||
struct StatsCollector {
|
||||
field: Field,
|
||||
field: String,
|
||||
}
|
||||
|
||||
impl StatsCollector {
|
||||
fn with_field(field: Field) -> StatsCollector {
|
||||
fn with_field(field: String) -> StatsCollector {
|
||||
StatsCollector { field }
|
||||
}
|
||||
}
|
||||
@@ -73,7 +73,7 @@ impl Collector for StatsCollector {
|
||||
_segment_local_id: u32,
|
||||
segment_reader: &SegmentReader,
|
||||
) -> 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 {
|
||||
fast_field_reader,
|
||||
stats: Stats::default(),
|
||||
@@ -171,7 +171,9 @@ fn main() -> tantivy::Result<()> {
|
||||
|
||||
// here we want to get a hit on the 'ken' in Frankenstein
|
||||
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!("mean: {}", stats.mean());
|
||||
println!("standard deviation: {}", stats.standard_deviation());
|
||||
|
||||
@@ -27,7 +27,7 @@ fn main() -> Result<()> {
|
||||
reader.reload()?;
|
||||
let searcher = reader.searcher();
|
||||
// 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
|
||||
let num_60s_books = searcher.search(&docs_in_the_sixties, &Count)?;
|
||||
assert_eq!(num_60s_books, 10);
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::sync::{Arc, RwLock, Weak};
|
||||
|
||||
use tantivy::collector::TopDocs;
|
||||
use tantivy::query::QueryParser;
|
||||
use tantivy::schema::{Field, Schema, FAST, TEXT};
|
||||
use tantivy::schema::{Schema, FAST, TEXT};
|
||||
use tantivy::{
|
||||
doc, DocAddress, DocId, Index, IndexReader, Opstamp, Searcher, SearcherGeneration, SegmentId,
|
||||
SegmentReader, Warmer,
|
||||
@@ -25,13 +25,13 @@ pub trait PriceFetcher: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
struct DynamicPriceColumn {
|
||||
field: Field,
|
||||
field: String,
|
||||
price_cache: RwLock<HashMap<(SegmentId, Option<Opstamp>), Arc<Vec<Price>>>>,
|
||||
price_fetcher: Box<dyn PriceFetcher>,
|
||||
}
|
||||
|
||||
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 {
|
||||
field,
|
||||
price_cache: Default::default(),
|
||||
@@ -48,7 +48,7 @@ impl Warmer for DynamicPriceColumn {
|
||||
fn warm(&self, searcher: &Searcher) -> tantivy::Result<()> {
|
||||
for segment in searcher.segment_readers() {
|
||||
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
|
||||
.doc_ids_alive()
|
||||
.map(|doc| product_id_reader.get_val(doc))
|
||||
@@ -123,7 +123,7 @@ fn main() -> tantivy::Result<()> {
|
||||
|
||||
let price_table = ExternalPriceTable::default();
|
||||
let price_dynamic_column = Arc::new(DynamicPriceColumn::with_product_id_field(
|
||||
product_id,
|
||||
"product_id".to_string(),
|
||||
price_table.clone(),
|
||||
));
|
||||
price_table.update_price(OLIVE_OIL, 12);
|
||||
|
||||
@@ -94,10 +94,7 @@ impl BucketAggregationWithAccessor {
|
||||
BucketAggregationType::Terms(TermsAggregation {
|
||||
field: field_name, ..
|
||||
}) => {
|
||||
let field = reader
|
||||
.schema()
|
||||
.get_field(field_name)
|
||||
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))?;
|
||||
let field = reader.schema().get_field(field_name)?;
|
||||
inverted_index = Some(reader.inverted_index(field)?);
|
||||
get_ff_reader_and_validate(reader, field_name, Cardinality::MultiValues)?
|
||||
}
|
||||
@@ -195,10 +192,7 @@ fn get_ff_reader_and_validate(
|
||||
field_name: &str,
|
||||
cardinality: Cardinality,
|
||||
) -> crate::Result<(FastFieldAccessor, Type)> {
|
||||
let field = reader
|
||||
.schema()
|
||||
.get_field(field_name)
|
||||
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))?;
|
||||
let field = reader.schema().get_field(field_name)?;
|
||||
let field_type = reader.schema().get_field_entry(field).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();
|
||||
match cardinality {
|
||||
Cardinality::SingleValue => ff_fields
|
||||
.u64_lenient(field)
|
||||
.u64_lenient(field_name)
|
||||
.map(|field| (FastFieldAccessor::Single(field), field_type.value_type())),
|
||||
Cardinality::MultiValues => ff_fields
|
||||
.u64s_lenient(field)
|
||||
.u64s_lenient(field_name)
|
||||
.map(|field| (FastFieldAccessor::Multi(field), field_type.value_type())),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
let field = schema
|
||||
.get_field(&histogram_req.field)
|
||||
.ok_or_else(|| TantivyError::FieldNotFound(histogram_req.field.to_string()))?;
|
||||
let field = schema.get_field(&histogram_req.field)?;
|
||||
if schema.get_field_entry(field).field_type().is_date() {
|
||||
for bucket in buckets.iter_mut() {
|
||||
if let crate::aggregation::Key::F64(val) = bucket.key {
|
||||
|
||||
@@ -26,7 +26,6 @@ use super::{format_date, Key, SerializedKey, VecWithNames};
|
||||
use crate::aggregation::agg_result::{AggregationResults, BucketEntries, BucketEntry};
|
||||
use crate::aggregation::bucket::TermsAggregationInternal;
|
||||
use crate::schema::Schema;
|
||||
use crate::TantivyError;
|
||||
|
||||
/// Contains the intermediate aggregation result, which is optimized to be merged with other
|
||||
/// 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
|
||||
// rfc339
|
||||
let field = schema
|
||||
.get_field(&range_req.field)
|
||||
.ok_or_else(|| TantivyError::FieldNotFound(range_req.field.to_string()))?;
|
||||
let field = schema.get_field(&range_req.field)?;
|
||||
if schema.get_field_entry(field).field_type().is_date() {
|
||||
if let Some(val) = range_bucket_entry.to {
|
||||
let key_as_string = format_date(val as i64)?;
|
||||
|
||||
@@ -130,7 +130,7 @@ where
|
||||
|
||||
let fast_field_reader = segment_reader
|
||||
.fast_fields()
|
||||
.typed_fast_field_reader(self.field)?;
|
||||
.typed_fast_field_reader(schema.get_field_name(self.field))?;
|
||||
|
||||
let segment_collector = self
|
||||
.collector
|
||||
|
||||
@@ -5,7 +5,7 @@ use fastfield_codecs::Column;
|
||||
|
||||
use crate::collector::{Collector, SegmentCollector};
|
||||
use crate::fastfield::FastValue;
|
||||
use crate::schema::{Field, Type};
|
||||
use crate::schema::Type;
|
||||
use crate::{DocId, Score};
|
||||
|
||||
/// Histogram builds an histogram of the values of a fastfield for the
|
||||
@@ -28,7 +28,7 @@ pub struct HistogramCollector {
|
||||
min_value: u64,
|
||||
num_buckets: usize,
|
||||
divider: DividerU64,
|
||||
field: Field,
|
||||
field: String,
|
||||
}
|
||||
|
||||
impl HistogramCollector {
|
||||
@@ -46,7 +46,7 @@ impl HistogramCollector {
|
||||
/// # Disclaimer
|
||||
/// This function panics if the field given is of type f64.
|
||||
pub fn new<TFastValue: FastValue>(
|
||||
field: Field,
|
||||
field: String,
|
||||
min_value: TFastValue,
|
||||
bucket_width: u64,
|
||||
num_buckets: usize,
|
||||
@@ -112,7 +112,7 @@ impl Collector for HistogramCollector {
|
||||
_segment_local_id: crate::SegmentOrdinal,
|
||||
segment: &crate::SegmentReader,
|
||||
) -> 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 {
|
||||
histogram_computer: HistogramComputer {
|
||||
counts: vec![0; self.num_buckets],
|
||||
@@ -211,13 +211,13 @@ mod tests {
|
||||
#[test]
|
||||
fn test_no_segments() -> crate::Result<()> {
|
||||
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 index = Index::create_in_ram(schema);
|
||||
let reader = index.reader()?;
|
||||
let searcher = reader.searcher();
|
||||
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)?;
|
||||
assert_eq!(histogram, vec![0; 5]);
|
||||
Ok(())
|
||||
@@ -238,7 +238,8 @@ mod tests {
|
||||
let reader = index.reader()?;
|
||||
let searcher = reader.searcher();
|
||||
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)?;
|
||||
assert_eq!(histogram, vec![1, 1, 0, 1]);
|
||||
Ok(())
|
||||
@@ -262,7 +263,8 @@ mod tests {
|
||||
let reader = index.reader()?;
|
||||
let searcher = reader.searcher();
|
||||
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)?;
|
||||
assert_eq!(histogram, vec![1, 1, 0, 1]);
|
||||
Ok(())
|
||||
@@ -285,7 +287,7 @@ mod tests {
|
||||
let searcher = reader.searcher();
|
||||
let all_query = AllQuery;
|
||||
let week_histogram_collector = HistogramCollector::new(
|
||||
date_field,
|
||||
"date_field".to_string(),
|
||||
DateTime::from_primitive(
|
||||
Date::from_calendar_date(1980, Month::January, 1)?.with_hms(0, 0, 0)?,
|
||||
),
|
||||
|
||||
@@ -155,7 +155,7 @@ impl SegmentCollector for TestSegmentCollector {
|
||||
///
|
||||
/// This collector is mainly useful for tests.
|
||||
pub struct FastFieldTestCollector {
|
||||
field: Field,
|
||||
field: String,
|
||||
}
|
||||
|
||||
pub struct FastFieldSegmentCollector {
|
||||
@@ -164,7 +164,7 @@ pub struct FastFieldSegmentCollector {
|
||||
}
|
||||
|
||||
impl FastFieldTestCollector {
|
||||
pub fn for_field(field: Field) -> FastFieldTestCollector {
|
||||
pub fn for_field(field: String) -> FastFieldTestCollector {
|
||||
FastFieldTestCollector { field }
|
||||
}
|
||||
}
|
||||
@@ -180,7 +180,7 @@ impl Collector for FastFieldTestCollector {
|
||||
) -> crate::Result<FastFieldSegmentCollector> {
|
||||
let reader = segment_reader
|
||||
.fast_fields()
|
||||
.u64(self.field)
|
||||
.u64(&self.field)
|
||||
.expect("Requested field is not a fast field.");
|
||||
Ok(FastFieldSegmentCollector {
|
||||
vals: Vec::new(),
|
||||
@@ -238,7 +238,9 @@ impl Collector for BytesFastFieldTestCollector {
|
||||
_segment_local_id: u32,
|
||||
segment_reader: &SegmentReader,
|
||||
) -> 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 {
|
||||
vals: Vec::new(),
|
||||
reader,
|
||||
|
||||
@@ -156,7 +156,7 @@ impl CustomScorer<u64> for ScorerByField {
|
||||
// The conversion will then happen only on the top-K docs.
|
||||
let ff_reader = segment_reader
|
||||
.fast_fields()
|
||||
.typed_fast_field_reader(self.field)?;
|
||||
.typed_fast_field_reader(segment_reader.schema().get_field_name(self.field))?;
|
||||
Ok(ScorerByFastFieldReader { ff_reader })
|
||||
}
|
||||
}
|
||||
@@ -454,7 +454,7 @@ impl TopDocs {
|
||||
/// // In our case, we will get a reader for the popularity
|
||||
/// // fast field.
|
||||
/// 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
|
||||
/// move |doc: DocId, original_score: Score| {
|
||||
@@ -561,9 +561,9 @@ impl TopDocs {
|
||||
/// // Note that this is implemented by using a `(u64, u64)`
|
||||
/// // as a score.
|
||||
/// let popularity_reader =
|
||||
/// segment_reader.fast_fields().u64(popularity).unwrap();
|
||||
/// segment_reader.fast_fields().u64("popularity").unwrap();
|
||||
/// 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
|
||||
/// move |doc: DocId| {
|
||||
|
||||
@@ -231,7 +231,7 @@ impl IndexBuilder {
|
||||
fn validate(&self) -> crate::Result<()> {
|
||||
if let Some(schema) = self.schema.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!(
|
||||
"Field to sort index {} not found in schema",
|
||||
sort_by_field.field
|
||||
|
||||
@@ -95,7 +95,8 @@ impl SegmentReader {
|
||||
|
||||
match field_entry.field_type() {
|
||||
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
|
||||
.termdict_composite
|
||||
.open_read(field)
|
||||
|
||||
@@ -25,7 +25,7 @@ mod tests {
|
||||
index_writer.commit()?;
|
||||
let searcher = index.reader()?.searcher();
|
||||
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!(bytes_reader.get_bytes(1).is_empty());
|
||||
assert_eq!(bytes_reader.get_bytes(2), &[255u8]);
|
||||
@@ -109,8 +109,7 @@ mod tests {
|
||||
let searcher = create_index_for_test(FAST)?;
|
||||
assert_eq!(searcher.num_docs(), 1);
|
||||
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(field).unwrap();
|
||||
let fast_field_reader = fast_fields.bytes("string_bytes").unwrap();
|
||||
assert_eq!(fast_field_reader.get_bytes(0u32), b"tantivy");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -583,7 +583,7 @@ mod tests {
|
||||
assert_eq!(searcher.segment_readers().len(), 1);
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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..5),
|
||||
@@ -622,7 +622,7 @@ mod tests {
|
||||
assert_eq!(searcher.segment_readers().len(), 2);
|
||||
let segment_reader = searcher.segment_reader(1);
|
||||
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]);
|
||||
}
|
||||
@@ -638,7 +638,7 @@ mod tests {
|
||||
let searcher = reader.searcher();
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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..8),
|
||||
@@ -681,7 +681,7 @@ mod tests {
|
||||
assert_eq!(searcher.segment_readers().len(), 1);
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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]);
|
||||
|
||||
@@ -712,7 +712,7 @@ mod tests {
|
||||
assert_eq!(searcher.segment_readers().len(), 2);
|
||||
let segment_reader = searcher.segment_reader(1);
|
||||
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]);
|
||||
}
|
||||
@@ -728,7 +728,7 @@ mod tests {
|
||||
let searcher = reader.searcher();
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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..9),
|
||||
@@ -773,8 +773,8 @@ mod tests {
|
||||
assert_eq!(searcher.segment_readers().len(), 1);
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
let fast_fields = segment_reader.fast_fields();
|
||||
let date_fast_field = fast_fields.date(date_field).unwrap();
|
||||
let dates_fast_field = fast_fields.dates(multi_date_field).unwrap();
|
||||
let date_fast_field = fast_fields.date("date").unwrap();
|
||||
let dates_fast_field = fast_fields.dates("multi_date").unwrap();
|
||||
let mut dates = vec![];
|
||||
{
|
||||
assert_eq!(date_fast_field.get_val(0).into_timestamp_micros(), 1i64);
|
||||
@@ -1014,7 +1014,7 @@ mod tests {
|
||||
let reader = index.reader().unwrap();
|
||||
let searcher = reader.searcher();
|
||||
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 test_range = |range: RangeInclusive<u64>| {
|
||||
@@ -1063,7 +1063,7 @@ mod tests {
|
||||
let reader = index.reader().unwrap();
|
||||
let searcher = reader.searcher();
|
||||
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 test_range = |range: RangeInclusive<u64>| {
|
||||
|
||||
@@ -52,7 +52,7 @@ mod tests {
|
||||
let searcher = index.reader()?.searcher();
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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);
|
||||
assert_eq!(&vals, &[4u64]);
|
||||
@@ -229,7 +229,7 @@ mod tests {
|
||||
let searcher = index.reader()?.searcher();
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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);
|
||||
assert_eq!(&vals, &[-4i64]);
|
||||
multi_value_reader.get_vals(0, &mut vals);
|
||||
@@ -261,7 +261,7 @@ mod tests {
|
||||
let searcher = index.reader()?.searcher();
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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);
|
||||
assert_eq!(&vals, &[false]);
|
||||
multi_value_reader.get_vals(0, &mut vals);
|
||||
|
||||
@@ -159,7 +159,7 @@ mod tests {
|
||||
let searcher = reader.searcher();
|
||||
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![];
|
||||
date_ff_reader.get_docids_for_value_range(
|
||||
DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead),
|
||||
@@ -173,7 +173,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_date(
|
||||
date_field,
|
||||
"multi_date_field".to_string(),
|
||||
DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead)
|
||||
)),
|
||||
1
|
||||
@@ -226,7 +226,7 @@ mod tests {
|
||||
let reader = searcher.segment_reader(0);
|
||||
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![];
|
||||
date_ff_reader.get_docids_for_value_range(
|
||||
DateTime::from_utc(first_time_stamp)..=DateTime::from_utc(two_secs_ahead),
|
||||
@@ -240,7 +240,7 @@ mod tests {
|
||||
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_date(
|
||||
date_field,
|
||||
"multi_date_field".to_string(),
|
||||
DateTime::from_utc(first_time_stamp)..DateTime::from_utc(two_secs_ahead)
|
||||
)),
|
||||
2
|
||||
@@ -324,7 +324,7 @@ mod tests {
|
||||
index_writer.commit()?;
|
||||
let searcher = index.reader()?.searcher();
|
||||
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.max_value(), 6);
|
||||
|
||||
@@ -114,9 +114,11 @@ impl FastFieldReaders {
|
||||
|
||||
pub(crate) fn typed_fast_field_reader_with_idx<TFastValue: FastValue>(
|
||||
&self,
|
||||
field: Field,
|
||||
field_name: &str,
|
||||
index: usize,
|
||||
) -> 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 bytes = fast_field_slice.read_bytes()?;
|
||||
let column = fastfield_codecs::open(bytes)?;
|
||||
@@ -125,32 +127,37 @@ impl FastFieldReaders {
|
||||
|
||||
pub(crate) fn typed_fast_field_reader<TFastValue: FastValue>(
|
||||
&self,
|
||||
field: Field,
|
||||
field_name: &str,
|
||||
) -> 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>(
|
||||
&self,
|
||||
field: Field,
|
||||
field_name: &str,
|
||||
) -> crate::Result<MultiValuedFastFieldReader<TFastValue>> {
|
||||
let idx_reader = self.typed_fast_field_reader(field)?;
|
||||
let vals_reader = self.typed_fast_field_reader_with_idx(field, 1)?;
|
||||
let idx_reader = self.typed_fast_field_reader(field_name)?;
|
||||
let vals_reader = self.typed_fast_field_reader_with_idx(field_name, 1)?;
|
||||
Ok(MultiValuedFastFieldReader::open(idx_reader, vals_reader))
|
||||
}
|
||||
|
||||
/// Returns the `u64` fast field reader reader associated with `field`.
|
||||
///
|
||||
/// 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>>> {
|
||||
self.check_type(field, FastType::U64, Cardinality::SingleValue)?;
|
||||
self.typed_fast_field_reader(field)
|
||||
pub fn u64(&self, field_name: &str) -> crate::Result<Arc<dyn Column<u64>>> {
|
||||
self.check_type(
|
||||
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`.
|
||||
///
|
||||
/// 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)?;
|
||||
let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
|
||||
Ok(open_u128::<Ipv6Addr>(bytes)?)
|
||||
@@ -159,9 +166,13 @@ impl FastFieldReaders {
|
||||
/// Returns the `ip` fast field reader reader associated to `field`.
|
||||
///
|
||||
/// 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)?;
|
||||
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 vals_reader = open_u128::<Ipv6Addr>(bytes)?;
|
||||
@@ -172,7 +183,8 @@ impl FastFieldReaders {
|
||||
/// Returns the `u128` fast field reader reader associated to `field`.
|
||||
///
|
||||
/// 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)?;
|
||||
let bytes = self.fast_field_data(field, 0)?.read_bytes()?;
|
||||
Ok(open_u128::<u128>(bytes)?)
|
||||
@@ -181,9 +193,11 @@ impl FastFieldReaders {
|
||||
/// 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.
|
||||
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)?;
|
||||
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 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
|
||||
/// FastValue.
|
||||
pub fn u64_lenient(&self, field: Field) -> crate::Result<Arc<dyn Column<u64>>> {
|
||||
self.typed_fast_field_reader(field)
|
||||
pub fn u64_lenient(&self, field_name: &str) -> crate::Result<Arc<dyn Column<u64>>> {
|
||||
self.typed_fast_field_reader(field_name)
|
||||
}
|
||||
|
||||
/// Returns the `i64` fast field reader reader associated with `field`.
|
||||
///
|
||||
/// 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.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`.
|
||||
///
|
||||
/// 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.typed_fast_field_reader(field)
|
||||
self.typed_fast_field_reader(field_name)
|
||||
}
|
||||
|
||||
/// Returns the `f64` fast field reader reader associated with `field`.
|
||||
///
|
||||
/// 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.typed_fast_field_reader(field)
|
||||
self.typed_fast_field_reader(field_name)
|
||||
}
|
||||
|
||||
/// Returns the `bool` fast field reader reader associated with `field`.
|
||||
///
|
||||
/// 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.typed_fast_field_reader(field)
|
||||
self.typed_fast_field_reader(field_name)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
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.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
|
||||
/// 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.
|
||||
pub fn u64s_lenient(&self, field: Field) -> crate::Result<MultiValuedFastFieldReader<u64>> {
|
||||
self.typed_fast_field_multi_reader(field)
|
||||
pub fn u64s_lenient(&self, field_name: &str) -> crate::Result<MultiValuedFastFieldReader<u64>> {
|
||||
self.typed_fast_field_multi_reader(field_name)
|
||||
}
|
||||
|
||||
/// 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.
|
||||
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.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`.
|
||||
///
|
||||
/// 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.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`.
|
||||
///
|
||||
/// 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.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
|
||||
@@ -277,15 +299,17 @@ impl FastFieldReaders {
|
||||
///
|
||||
/// If `field` is not a `time::OffsetDateTime` multi-valued fast field, this method returns an
|
||||
/// 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.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`.
|
||||
///
|
||||
/// 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);
|
||||
if let FieldType::Bytes(bytes_option) = field_entry.field_type() {
|
||||
if !bytes_option.is_fast() {
|
||||
|
||||
@@ -99,7 +99,7 @@ pub(crate) fn expect_field_id_for_sort_field(
|
||||
schema: &Schema,
|
||||
sort_by_field: &IndexSortByField,
|
||||
) -> 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!(
|
||||
"field to sort index by not found: {:?}",
|
||||
sort_by_field.field
|
||||
@@ -462,15 +462,14 @@ mod tests_indexsorting {
|
||||
assert_eq!(searcher.segment_readers().len(), 1);
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
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(1), 20u64);
|
||||
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![];
|
||||
multifield.get_vals(0u32, &mut vals);
|
||||
assert_eq!(vals, &[] as &[u64]);
|
||||
|
||||
@@ -1465,7 +1465,7 @@ mod tests {
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
assert_eq!(segment_reader.num_docs(), 8);
|
||||
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
|
||||
.doc_ids_alive()
|
||||
.map(|doc| fast_field_reader.get_val(doc))
|
||||
@@ -1526,7 +1526,7 @@ mod tests {
|
||||
let segment_reader = searcher.segment_reader(0);
|
||||
assert_eq!(segment_reader.num_docs(), 8);
|
||||
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
|
||||
.doc_ids_alive()
|
||||
.map(|doc| fast_field_reader.get_val(doc))
|
||||
@@ -1778,7 +1778,7 @@ mod tests {
|
||||
.segment_readers()
|
||||
.iter()
|
||||
.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
|
||||
.doc_ids_alive()
|
||||
.map(move |doc| ff_reader.get_val(doc))
|
||||
@@ -1789,7 +1789,7 @@ mod tests {
|
||||
.segment_readers()
|
||||
.iter()
|
||||
.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
|
||||
.doc_ids_alive()
|
||||
.map(move |doc| ff_reader.get_val(doc))
|
||||
@@ -1804,7 +1804,7 @@ mod tests {
|
||||
let mut all_ips = Vec::new();
|
||||
let mut num_ips = 0;
|
||||
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() {
|
||||
let mut vals = vec![];
|
||||
ip_reader.get_vals(doc, &mut vals);
|
||||
@@ -1851,7 +1851,7 @@ mod tests {
|
||||
.segment_readers()
|
||||
.iter()
|
||||
.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
|
||||
})
|
||||
.sum();
|
||||
@@ -1863,7 +1863,7 @@ mod tests {
|
||||
.segment_readers()
|
||||
.iter()
|
||||
.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| {
|
||||
let val = ff_reader.get_val(doc);
|
||||
if val == Ipv6Addr::from_u128(0) {
|
||||
@@ -1902,7 +1902,7 @@ mod tests {
|
||||
.segment_readers()
|
||||
.iter()
|
||||
.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| {
|
||||
let mut vals = vec![];
|
||||
ff_reader.get_vals(doc, &mut vals);
|
||||
@@ -1914,9 +1914,9 @@ mod tests {
|
||||
|
||||
// multivalue fast field tests
|
||||
for segment_reader in searcher.segment_readers().iter() {
|
||||
let id_reader = segment_reader.fast_fields().u64(id_field).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 id_reader = segment_reader.fast_fields().u64("id").unwrap();
|
||||
let ff_reader = segment_reader.fast_fields().u64s("multi_numbers").unwrap();
|
||||
let bool_ff_reader = segment_reader.fast_fields().bools("multi_bools").unwrap();
|
||||
for doc in segment_reader.doc_ids_alive() {
|
||||
let mut vals = vec![];
|
||||
ff_reader.get_vals(doc, &mut vals);
|
||||
@@ -2109,7 +2109,7 @@ mod tests {
|
||||
// test facets
|
||||
for segment_reader in searcher.segment_readers().iter() {
|
||||
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() {
|
||||
let mut facet_ords = Vec::new();
|
||||
facet_reader.facet_ords(doc_id, &mut facet_ords);
|
||||
|
||||
@@ -16,7 +16,7 @@ use crate::fastfield::{
|
||||
MultiValueIndex, MultiValuedFastFieldReader,
|
||||
};
|
||||
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_multivalue_column::RemappedDocIdMultiValueColumn;
|
||||
use crate::indexer::SegmentSerializer;
|
||||
@@ -335,8 +335,10 @@ impl IndexMerger {
|
||||
.readers
|
||||
.iter()
|
||||
.map(|segment_reader| {
|
||||
let ff_reader: MultiValuedFastFieldReader<u128> =
|
||||
segment_reader.fast_fields().u128s(field).expect(
|
||||
let ff_reader: MultiValuedFastFieldReader<u128> = segment_reader
|
||||
.fast_fields()
|
||||
.u128s(self.schema.get_field_name(field))
|
||||
.expect(
|
||||
"Failed to find index for multivalued field. This is a bug in tantivy, \
|
||||
please report.",
|
||||
);
|
||||
@@ -401,10 +403,13 @@ impl IndexMerger {
|
||||
.readers
|
||||
.iter()
|
||||
.map(|reader| {
|
||||
let u128_reader: Arc<dyn Column<u128>> = reader.fast_fields().u128(field).expect(
|
||||
"Failed to find a reader for single fast field. This is a tantivy bug and it \
|
||||
should never happen.",
|
||||
);
|
||||
let u128_reader: Arc<dyn Column<u128>> = reader
|
||||
.fast_fields()
|
||||
.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
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -431,7 +436,11 @@ impl IndexMerger {
|
||||
fast_field_serializer: &mut CompositeFastFieldSerializer,
|
||||
doc_id_mapping: &SegmentDocIdMapping,
|
||||
) -> 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)?;
|
||||
|
||||
Ok(())
|
||||
@@ -464,8 +473,8 @@ impl IndexMerger {
|
||||
reader: &SegmentReader,
|
||||
sort_by_field: &IndexSortByField,
|
||||
) -> 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
|
||||
let value_accessor = reader.fast_fields().u64_lenient(field_id)?;
|
||||
reader.schema().get_field(&sort_by_field.field)?;
|
||||
let value_accessor = reader.fast_fields().u64_lenient(&sort_by_field.field)?;
|
||||
Ok(value_accessor)
|
||||
}
|
||||
/// Collecting value_accessors into a vec to bind the lifetime.
|
||||
@@ -569,7 +578,7 @@ impl IndexMerger {
|
||||
.map(|reader| {
|
||||
let u64s_reader: MultiValuedFastFieldReader<u64> = reader
|
||||
.fast_fields()
|
||||
.typed_fast_field_multi_reader::<u64>(field)
|
||||
.typed_fast_field_multi_reader::<u64>(self.schema.get_field_name(field))
|
||||
.expect(
|
||||
"Failed to find index for multivalued field. This is a bug in tantivy, \
|
||||
please report.",
|
||||
@@ -613,7 +622,7 @@ impl IndexMerger {
|
||||
.map(|reader| {
|
||||
let ff_reader: MultiValuedFastFieldReader<u64> = reader
|
||||
.fast_fields()
|
||||
.u64s(field)
|
||||
.u64s(self.schema.get_field_name(field))
|
||||
.expect("Could not find multivalued u64 fast value reader.");
|
||||
ff_reader
|
||||
})
|
||||
@@ -684,8 +693,11 @@ impl IndexMerger {
|
||||
|
||||
self.write_multi_value_fast_field_idx(field, fast_field_serializer, doc_id_mapping)?;
|
||||
|
||||
let fastfield_accessor =
|
||||
RemappedDocIdMultiValueColumn::new(&self.readers, doc_id_mapping, field);
|
||||
let fastfield_accessor = RemappedDocIdMultiValueColumn::new(
|
||||
&self.readers,
|
||||
doc_id_mapping,
|
||||
self.schema.get_field_name(field),
|
||||
);
|
||||
fast_field_serializer.create_auto_detect_u64_fast_field_with_idx_and_codecs(
|
||||
field,
|
||||
fastfield_accessor,
|
||||
@@ -706,10 +718,13 @@ impl IndexMerger {
|
||||
.readers
|
||||
.iter()
|
||||
.map(|reader| {
|
||||
let bytes_reader = reader.fast_fields().bytes(field).expect(
|
||||
"Failed to find index for bytes field. This is a bug in tantivy, please \
|
||||
report.",
|
||||
);
|
||||
let bytes_reader = reader
|
||||
.fast_fields()
|
||||
.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)
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
@@ -1206,7 +1221,10 @@ mod tests {
|
||||
{
|
||||
let get_fast_vals = |terms: Vec<Term>| {
|
||||
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 query = BooleanQuery::new_multiterms_query(terms);
|
||||
@@ -1244,7 +1262,7 @@ mod tests {
|
||||
let mut index_writer = index.writer_for_tests()?;
|
||||
let reader = index.reader().unwrap();
|
||||
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 term_query = TermQuery::new(term, IndexRecordOption::Basic);
|
||||
searcher
|
||||
@@ -1366,7 +1384,7 @@ mod tests {
|
||||
let score_field_reader = searcher
|
||||
.segment_reader(0)
|
||||
.fast_fields()
|
||||
.u64(score_field)
|
||||
.u64("score")
|
||||
.unwrap();
|
||||
assert_eq!(score_field_reader.min_value(), 4000);
|
||||
assert_eq!(score_field_reader.max_value(), 7000);
|
||||
@@ -1374,7 +1392,7 @@ mod tests {
|
||||
let score_field_reader = searcher
|
||||
.segment_reader(1)
|
||||
.fast_fields()
|
||||
.u64(score_field)
|
||||
.u64("score")
|
||||
.unwrap();
|
||||
assert_eq!(score_field_reader.min_value(), 1);
|
||||
assert_eq!(score_field_reader.max_value(), 3);
|
||||
@@ -1420,7 +1438,7 @@ mod tests {
|
||||
let score_field_reader = searcher
|
||||
.segment_reader(0)
|
||||
.fast_fields()
|
||||
.u64(score_field)
|
||||
.u64("score")
|
||||
.unwrap();
|
||||
assert_eq!(score_field_reader.min_value(), 3);
|
||||
assert_eq!(score_field_reader.max_value(), 7000);
|
||||
@@ -1467,7 +1485,7 @@ mod tests {
|
||||
let score_field_reader = searcher
|
||||
.segment_reader(0)
|
||||
.fast_fields()
|
||||
.u64(score_field)
|
||||
.u64("score")
|
||||
.unwrap();
|
||||
assert_eq!(score_field_reader.min_value(), 3);
|
||||
assert_eq!(score_field_reader.max_value(), 7000);
|
||||
@@ -1514,7 +1532,7 @@ mod tests {
|
||||
let score_field_reader = searcher
|
||||
.segment_reader(0)
|
||||
.fast_fields()
|
||||
.u64(score_field)
|
||||
.u64("score")
|
||||
.unwrap();
|
||||
assert_eq!(score_field_reader.min_value(), 6000);
|
||||
assert_eq!(score_field_reader.max_value(), 7000);
|
||||
@@ -1836,7 +1854,7 @@ mod tests {
|
||||
|
||||
{
|
||||
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);
|
||||
assert_eq!(&vals, &[1, 2]);
|
||||
@@ -1862,7 +1880,7 @@ mod tests {
|
||||
|
||||
{
|
||||
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);
|
||||
assert_eq!(&vals, &[28, 27]);
|
||||
|
||||
@@ -1872,7 +1890,7 @@ mod tests {
|
||||
|
||||
{
|
||||
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);
|
||||
assert_eq!(&vals, &[20]);
|
||||
}
|
||||
@@ -1889,7 +1907,7 @@ mod tests {
|
||||
{
|
||||
let searcher = reader.searcher();
|
||||
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);
|
||||
assert_eq!(&vals, &[1, 2]);
|
||||
|
||||
@@ -185,7 +185,7 @@ mod tests {
|
||||
let segment_reader = searcher.segment_readers().last().unwrap();
|
||||
|
||||
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(4), 2u64);
|
||||
assert_eq!(fast_field.get_val(3), 3u64);
|
||||
@@ -364,15 +364,13 @@ mod tests {
|
||||
.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 searcher = reader.searcher();
|
||||
assert_eq!(searcher.segment_readers().len(), 1);
|
||||
let segment_reader = searcher.segment_readers().last().unwrap();
|
||||
|
||||
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(1), 2u64);
|
||||
assert_eq!(fast_field.get_val(2), 3u64);
|
||||
@@ -386,7 +384,7 @@ mod tests {
|
||||
vals
|
||||
};
|
||||
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, 1), &[2, 3]);
|
||||
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, 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(2), &[1, 2, 3]);
|
||||
assert_eq!(fast_field.get_bytes(5), &[5, 5]);
|
||||
@@ -527,7 +525,6 @@ mod bench_sorted_index_merge {
|
||||
order: Order::Desc,
|
||||
};
|
||||
let index = create_index(Some(sort_by_field.clone()));
|
||||
let field = index.schema().get_field("intval").unwrap();
|
||||
let segments = index.searchable_segments().unwrap();
|
||||
let merger: IndexMerger =
|
||||
IndexMerger::open(index.schema(), index.settings().clone(), &segments[..])?;
|
||||
@@ -535,8 +532,10 @@ mod bench_sorted_index_merge {
|
||||
b.iter(|| {
|
||||
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 u64_reader: Arc<dyn Column<u64>> =
|
||||
reader.fast_fields().typed_fast_field_reader(field).expect(
|
||||
let u64_reader: Arc<dyn Column<u64>> = reader
|
||||
.fast_fields()
|
||||
.typed_fast_field_reader("intval")
|
||||
.expect(
|
||||
"Failed to find a reader for single fast field. This is a tantivy bug and \
|
||||
it should never happen.",
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ use fastfield_codecs::Column;
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::indexer::doc_id_mapping::SegmentDocIdMapping;
|
||||
use crate::schema::Field;
|
||||
use crate::SegmentReader;
|
||||
|
||||
pub(crate) struct RemappedDocIdColumn<'a> {
|
||||
@@ -41,7 +40,7 @@ impl<'a> RemappedDocIdColumn<'a> {
|
||||
pub(crate) fn new(
|
||||
readers: &'a [SegmentReader],
|
||||
doc_id_mapping: &'a SegmentDocIdMapping,
|
||||
field: Field,
|
||||
field: &str,
|
||||
) -> Self {
|
||||
let (min_value, max_value) = readers
|
||||
.iter()
|
||||
|
||||
@@ -5,7 +5,6 @@ use fastfield_codecs::Column;
|
||||
use super::flat_map_with_buffer::FlatMapWithBufferIter;
|
||||
use crate::fastfield::{MultiValueIndex, MultiValuedFastFieldReader};
|
||||
use crate::indexer::doc_id_mapping::SegmentDocIdMapping;
|
||||
use crate::schema::Field;
|
||||
use crate::{DocAddress, SegmentReader};
|
||||
|
||||
pub(crate) struct RemappedDocIdMultiValueColumn<'a> {
|
||||
@@ -20,7 +19,7 @@ impl<'a> RemappedDocIdMultiValueColumn<'a> {
|
||||
pub(crate) fn new(
|
||||
readers: &'a [SegmentReader],
|
||||
doc_id_mapping: &'a SegmentDocIdMapping,
|
||||
field: Field,
|
||||
field: &str,
|
||||
) -> Self {
|
||||
// Our values are bitpacked and we need to know what should be
|
||||
// our bitwidth and our minimum value before serializing any values.
|
||||
|
||||
18
src/lib.rs
18
src/lib.rs
@@ -995,8 +995,8 @@ pub mod tests {
|
||||
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_float = schema_builder.add_f64_field("float", FAST);
|
||||
let text_field = schema_builder.add_text_field("text", TEXT);
|
||||
let stored_int_field = schema_builder.add_u64_field("stored_int", STORED);
|
||||
schema_builder.add_text_field("text", TEXT);
|
||||
schema_builder.add_u64_field("stored_int", STORED);
|
||||
let schema = schema_builder.build();
|
||||
|
||||
let index = Index::create_in_ram(schema);
|
||||
@@ -1011,37 +1011,37 @@ pub mod tests {
|
||||
let searcher = reader.searcher();
|
||||
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());
|
||||
}
|
||||
{
|
||||
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());
|
||||
}
|
||||
{
|
||||
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());
|
||||
}
|
||||
{
|
||||
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());
|
||||
}
|
||||
{
|
||||
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());
|
||||
let fast_field_reader = fast_field_reader_opt.unwrap();
|
||||
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());
|
||||
let fast_field_reader = fast_field_reader_res.unwrap();
|
||||
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());
|
||||
let fast_field_reader = fast_field_reader_res.unwrap();
|
||||
assert_eq!(fast_field_reader.get_val(0), 4f64)
|
||||
|
||||
@@ -10,7 +10,7 @@ pub enum LogicalLiteral {
|
||||
Term(Term),
|
||||
Phrase(Vec<(usize, Term)>, u32),
|
||||
Range {
|
||||
field: Field,
|
||||
field: String,
|
||||
value_type: Type,
|
||||
lower: Bound<Term>,
|
||||
upper: Bound<Term>,
|
||||
|
||||
@@ -672,7 +672,7 @@ impl QueryParser {
|
||||
let field_entry = self.schema.get_field_entry(field);
|
||||
let value_type = field_entry.field_type().value_type();
|
||||
let logical_ast = LogicalAst::Leaf(Box::new(LogicalLiteral::Range {
|
||||
field,
|
||||
field: self.schema.get_field_name(field).to_string(),
|
||||
value_type,
|
||||
lower: self.resolve_bound(field, json_path, &lower)?,
|
||||
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();
|
||||
assert_eq!(
|
||||
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]) }"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ pub(crate) fn map_bound<TFrom, TTo, Transform: Fn(&TFrom) -> TTo>(
|
||||
///
|
||||
/// let reader = index.reader()?;
|
||||
/// 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)?;
|
||||
/// assert_eq!(num_60s_books, 2285);
|
||||
/// Ok(())
|
||||
@@ -76,7 +76,7 @@ pub(crate) fn map_bound<TFrom, TTo, Transform: Fn(&TFrom) -> TTo>(
|
||||
/// ```
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct RangeQuery {
|
||||
field: Field,
|
||||
field: String,
|
||||
value_type: Type,
|
||||
left_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
|
||||
/// the `Weight` object is created.
|
||||
pub fn new_term_bounds(
|
||||
field: Field,
|
||||
field: String,
|
||||
value_type: Type,
|
||||
left_bound: &Bound<Term>,
|
||||
right_bound: &Bound<Term>,
|
||||
) -> RangeQuery {
|
||||
let verify_and_unwrap_term = |val: &Term| {
|
||||
assert_eq!(field, val.field());
|
||||
val.value_bytes().to_owned()
|
||||
};
|
||||
let verify_and_unwrap_term = |val: &Term| val.value_bytes().to_owned();
|
||||
RangeQuery {
|
||||
field,
|
||||
value_type,
|
||||
@@ -109,7 +106,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `i64`, tantivy
|
||||
/// 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(
|
||||
field,
|
||||
Bound::Included(range.start),
|
||||
@@ -125,11 +122,15 @@ impl RangeQuery {
|
||||
/// If the field is not of the type `i64`, tantivy
|
||||
/// will panic when the `Weight` object is created.
|
||||
pub fn new_i64_bounds(
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<i64>,
|
||||
right_bound: Bound<i64>,
|
||||
) -> 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 {
|
||||
field,
|
||||
value_type: Type::I64,
|
||||
@@ -142,7 +143,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `f64`, tantivy
|
||||
/// 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(
|
||||
field,
|
||||
Bound::Included(range.start),
|
||||
@@ -158,11 +159,15 @@ impl RangeQuery {
|
||||
/// If the field is not of the type `f64`, tantivy
|
||||
/// will panic when the `Weight` object is created.
|
||||
pub fn new_f64_bounds(
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<f64>,
|
||||
right_bound: Bound<f64>,
|
||||
) -> 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 {
|
||||
field,
|
||||
value_type: Type::F64,
|
||||
@@ -179,11 +184,15 @@ impl RangeQuery {
|
||||
/// If the field is not of the type `u64`, tantivy
|
||||
/// will panic when the `Weight` object is created.
|
||||
pub fn new_u64_bounds(
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<u64>,
|
||||
right_bound: Bound<u64>,
|
||||
) -> 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 {
|
||||
field,
|
||||
value_type: Type::U64,
|
||||
@@ -196,7 +205,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `u64`, tantivy
|
||||
/// 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(
|
||||
field,
|
||||
Bound::Included(range.start),
|
||||
@@ -212,12 +221,15 @@ impl RangeQuery {
|
||||
/// If the field is not of the type `date`, tantivy
|
||||
/// will panic when the `Weight` object is created.
|
||||
pub fn new_date_bounds(
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<DateTime>,
|
||||
right_bound: Bound<DateTime>,
|
||||
) -> RangeQuery {
|
||||
let make_term_val =
|
||||
|val: &DateTime| Term::from_field_date(field, *val).value_bytes().to_owned();
|
||||
let make_term_val = |val: &DateTime| {
|
||||
Term::from_field_date(Field::from_field_id(0), *val)
|
||||
.value_bytes()
|
||||
.to_owned()
|
||||
};
|
||||
RangeQuery {
|
||||
field,
|
||||
value_type: Type::Date,
|
||||
@@ -230,7 +242,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `date`, tantivy
|
||||
/// 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(
|
||||
field,
|
||||
Bound::Included(range.start),
|
||||
@@ -245,7 +257,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `Str`, tantivy
|
||||
/// 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();
|
||||
RangeQuery {
|
||||
field,
|
||||
@@ -259,7 +271,7 @@ impl RangeQuery {
|
||||
///
|
||||
/// If the field is not of the type `Str`, tantivy
|
||||
/// 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(
|
||||
field,
|
||||
Bound::Included(range.start),
|
||||
@@ -268,22 +280,8 @@ impl RangeQuery {
|
||||
}
|
||||
|
||||
/// Field to search over
|
||||
pub fn field(&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)
|
||||
})
|
||||
pub fn field(&self) -> &str {
|
||||
&self.field
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +305,9 @@ pub(crate) fn maps_to_u64_fastfield(typ: Type) -> bool {
|
||||
impl Query for RangeQuery {
|
||||
fn weight(&self, enable_scoring: EnableScoring<'_>) -> crate::Result<Box<dyn Weight>> {
|
||||
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();
|
||||
if value_type != self.value_type {
|
||||
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_ip_addr() {
|
||||
Ok(Box::new(IPFastFieldRangeWeight::new(
|
||||
self.field,
|
||||
self.field.to_string(),
|
||||
&self.left_bound,
|
||||
&self.right_bound,
|
||||
)))
|
||||
@@ -335,14 +335,14 @@ impl Query for RangeQuery {
|
||||
let left_bound = map_bound(&self.left_bound, &parse_from_bytes);
|
||||
let right_bound = map_bound(&self.right_bound, &parse_from_bytes);
|
||||
Ok(Box::new(FastFieldRangeWeight::new(
|
||||
self.field,
|
||||
self.field.to_string(),
|
||||
left_bound,
|
||||
right_bound,
|
||||
)))
|
||||
}
|
||||
} else {
|
||||
Ok(Box::new(RangeWeight {
|
||||
field: self.field,
|
||||
field: self.field.to_string(),
|
||||
left_bound: self.left_bound.clone(),
|
||||
right_bound: self.right_bound.clone(),
|
||||
}))
|
||||
@@ -351,7 +351,7 @@ impl Query for RangeQuery {
|
||||
}
|
||||
|
||||
pub struct RangeWeight {
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<Vec<u8>>,
|
||||
right_bound: Bound<Vec<u8>>,
|
||||
}
|
||||
@@ -379,7 +379,7 @@ impl Weight for RangeWeight {
|
||||
let max_doc = reader.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 mut term_range = self.term_range(term_dict)?;
|
||||
while term_range.advance() {
|
||||
@@ -443,7 +443,7 @@ mod tests {
|
||||
let reader = index.reader()?;
|
||||
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.
|
||||
let count = searcher.search(&docs_in_the_sixties, &Count)?;
|
||||
@@ -481,10 +481,13 @@ mod tests {
|
||||
let count_multiples =
|
||||
|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!(
|
||||
count_multiples(RangeQuery::new_i64_bounds(
|
||||
int_field,
|
||||
"intfield".to_string(),
|
||||
Bound::Included(10),
|
||||
Bound::Included(11)
|
||||
)),
|
||||
@@ -492,7 +495,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_i64_bounds(
|
||||
int_field,
|
||||
"intfield".to_string(),
|
||||
Bound::Excluded(9),
|
||||
Bound::Included(10)
|
||||
)),
|
||||
@@ -500,7 +503,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_i64_bounds(
|
||||
int_field,
|
||||
"intfield".to_string(),
|
||||
Bound::Included(9),
|
||||
Bound::Unbounded
|
||||
)),
|
||||
@@ -540,12 +543,12 @@ mod tests {
|
||||
|range_query: RangeQuery| searcher.search(&range_query, &Count).unwrap();
|
||||
|
||||
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
|
||||
);
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_f64_bounds(
|
||||
float_field,
|
||||
"floatfield".to_string(),
|
||||
Bound::Included(10.0),
|
||||
Bound::Included(11.0)
|
||||
)),
|
||||
@@ -553,7 +556,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_f64_bounds(
|
||||
float_field,
|
||||
"floatfield".to_string(),
|
||||
Bound::Excluded(9.0),
|
||||
Bound::Included(10.0)
|
||||
)),
|
||||
@@ -561,7 +564,7 @@ mod tests {
|
||||
);
|
||||
assert_eq!(
|
||||
count_multiples(RangeQuery::new_f64_bounds(
|
||||
float_field,
|
||||
"floatfield".to_string(),
|
||||
Bound::Included(9.0),
|
||||
Bound::Unbounded
|
||||
)),
|
||||
|
||||
@@ -11,18 +11,18 @@ use fastfield_codecs::MonotonicallyMappableToU128;
|
||||
use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet};
|
||||
use super::range_query::map_bound;
|
||||
use crate::query::{ConstScorer, Explanation, Scorer, Weight};
|
||||
use crate::schema::{Cardinality, Field};
|
||||
use crate::schema::Cardinality;
|
||||
use crate::{DocId, DocSet, Score, SegmentReader, TantivyError};
|
||||
|
||||
/// `IPFastFieldRangeWeight` uses the ip address fast field to execute range queries.
|
||||
pub struct IPFastFieldRangeWeight {
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<Ipv6Addr>,
|
||||
right_bound: Bound<Ipv6Addr>,
|
||||
}
|
||||
|
||||
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 ip_u128: u128 =
|
||||
u128::from_be(BinarySerializable::deserialize(&mut &data[..]).unwrap());
|
||||
@@ -40,10 +40,13 @@ impl IPFastFieldRangeWeight {
|
||||
|
||||
impl Weight for IPFastFieldRangeWeight {
|
||||
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() {
|
||||
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(
|
||||
&self.left_bound,
|
||||
&self.right_bound,
|
||||
@@ -57,7 +60,7 @@ impl Weight for IPFastFieldRangeWeight {
|
||||
Ok(Box::new(ConstScorer::new(docset, boost)))
|
||||
}
|
||||
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(
|
||||
&self.left_bound,
|
||||
&self.right_bound,
|
||||
|
||||
@@ -9,18 +9,18 @@ use fastfield_codecs::MonotonicallyMappableToU64;
|
||||
use super::fast_field_range_query::{FastFieldCardinality, RangeDocSet};
|
||||
use super::range_query::map_bound;
|
||||
use crate::query::{ConstScorer, Explanation, Scorer, Weight};
|
||||
use crate::schema::{Cardinality, Field};
|
||||
use crate::schema::Cardinality;
|
||||
use crate::{DocId, DocSet, Score, SegmentReader, TantivyError};
|
||||
|
||||
/// `FastFieldRangeWeight` uses the fast field to execute range queries.
|
||||
pub struct FastFieldRangeWeight {
|
||||
field: Field,
|
||||
field: String,
|
||||
left_bound: Bound<u64>,
|
||||
right_bound: Bound<u64>,
|
||||
}
|
||||
|
||||
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 right_bound = map_bound(&right_bound, &|val| *val);
|
||||
Self {
|
||||
@@ -33,10 +33,13 @@ impl FastFieldRangeWeight {
|
||||
|
||||
impl Weight for FastFieldRangeWeight {
|
||||
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() {
|
||||
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(
|
||||
&self.left_bound,
|
||||
&self.right_bound,
|
||||
@@ -48,7 +51,7 @@ impl Weight for FastFieldRangeWeight {
|
||||
Ok(Box::new(ConstScorer::new(docset, boost)))
|
||||
}
|
||||
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(
|
||||
&self.left_bound,
|
||||
&self.right_bound,
|
||||
|
||||
@@ -11,6 +11,7 @@ use super::ip_options::IpAddrOptions;
|
||||
use super::*;
|
||||
use crate::schema::bytes_options::BytesOptions;
|
||||
use crate::schema::field_type::ValueParsingError;
|
||||
use crate::TantivyError;
|
||||
|
||||
/// Tantivy has a very strict schema.
|
||||
/// 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.
|
||||
pub fn get_field(&self, field_name: &str) -> Option<Field> {
|
||||
self.0.fields_map.get(field_name).cloned()
|
||||
pub fn get_field(&self, field_name: &str) -> crate::Result<Field> {
|
||||
self.0
|
||||
.fields_map
|
||||
.get(field_name)
|
||||
.cloned()
|
||||
.ok_or_else(|| TantivyError::FieldNotFound(field_name.to_string()))
|
||||
}
|
||||
|
||||
/// Create document from a named doc.
|
||||
@@ -319,7 +324,7 @@ impl Schema {
|
||||
) -> Result<Document, DocParsingError> {
|
||||
let mut document = Document::new();
|
||||
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 {
|
||||
document.add_field_value(field, value);
|
||||
}
|
||||
@@ -360,7 +365,7 @@ impl Schema {
|
||||
) -> Result<Document, DocParsingError> {
|
||||
let mut doc = Document::default();
|
||||
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_type = field_entry.field_type();
|
||||
match json_value {
|
||||
|
||||
Reference in New Issue
Block a user