fix: Add support for bool to the fast field TermSet implementation (#70)

Missed in #69.

The `TermSet` fast fields implementation cribbed from `RangeQuery`'s fast fields implementation: ... which also has this bug. Will fix upstream.
This commit is contained in:
Stu Hood
2025-10-16 12:21:04 -07:00
committed by Stu Hood
parent 9fe0899934
commit e0476d2eb2
2 changed files with 47 additions and 15 deletions

View File

@@ -45,19 +45,17 @@ impl TermSetQuery {
return Err(crate::TantivyError::SchemaError(error_msg));
}
let supported_for_ff = sorted_terms
.get(0)
.map(|term| match term.typ() {
Type::U64 | Type::I64 | Type::F64 | Type::Bool | Type::Date | Type::IpAddr => {
true
}
Type::Json | Type::Str => {
// Explicitly not supported yet: see `term_set_query_fastfield.rs`.
false
}
_ => false,
})
.unwrap_or(false);
let supported_for_ff = match field_type.value_type() {
Type::U64 | Type::I64 | Type::F64 | Type::Bool | Type::Date | Type::IpAddr => {
// NOTE: Keep in sync with `FastFieldTermSetWeight::scorer`.
true
}
Type::Json | Type::Str => {
// Explicitly not supported yet: see `term_set_query_fastfield.rs`.
false
}
_ => false,
};
if field_type.is_fast() && supported_for_ff {
sub_queries.push((

View File

@@ -102,7 +102,9 @@ impl Weight for FastFieldTermSetWeight {
let docset = TermSetDocSet::new(ip_addr_column, values);
Ok(Box::new(ConstScorer::new(docset, boost)))
} else {
// Numeric types
// Numeric types.
//
// NOTE: Keep in sync with `TermSetQuery::specialized_weight`.
let mut values = HashSet::new();
for term in &self.terms {
let value = term.value();
@@ -112,11 +114,13 @@ impl Weight for FastFieldTermSetWeight {
val.to_u64()
} else if let Some(val) = value.as_f64() {
val.to_u64()
} else if let Some(val) = value.as_bool() {
val.to_u64()
} else if let Some(val) = value.as_date() {
val.to_u64()
} else {
return Err(crate::TantivyError::InvalidArgument(format!(
"Expected term with u64, i64, f64 or date, but got {:?}",
"Expected term with u64, i64, f64, bool, or date, but got {:?}",
term
)));
};
@@ -129,6 +133,7 @@ impl Weight for FastFieldTermSetWeight {
ColumnType::U64,
ColumnType::I64,
ColumnType::F64,
ColumnType::Bool,
ColumnType::DateTime,
]),
field_name,
@@ -229,6 +234,7 @@ mod tests {
let text_field_fast = schema_builder.add_text_field("text_fast", STRING | FAST);
let u64_field_fast = schema_builder.add_u64_field("u64_fast", FAST | INDEXED);
let ip_field_fast = schema_builder.add_ip_addr_field("ip_fast", FAST | INDEXED);
let bool_field_fast = schema_builder.add_bool_field("bool_fast", FAST | INDEXED);
let schema = schema_builder.build();
let index = Index::create_in_ram(schema);
{
@@ -238,18 +244,21 @@ mod tests {
text_field_fast => "doc1",
u64_field_fast => 1u64,
ip_field_fast => IpAddr::from_str("127.0.0.1").unwrap().into_ipv6_addr(),
bool_field_fast => true,
))?;
index_writer.add_document(doc!(
text_field => "doc2",
text_field_fast => "doc2",
u64_field_fast => 2u64,
ip_field_fast => IpAddr::from_str("127.0.0.2").unwrap().into_ipv6_addr(),
bool_field_fast => false,
))?;
index_writer.add_document(doc!(
text_field => "doc3",
text_field_fast => "doc3",
u64_field_fast => 3u64,
ip_field_fast => IpAddr::from_str("::ffff:127.0.0.3").unwrap().into_ipv6_addr(),
bool_field_fast => true,
))?;
index_writer.commit()?;
}
@@ -310,6 +319,27 @@ mod tests {
let count = searcher.search(&query, &Count)?;
assert_eq!(count, 2);
Ok(())
}
#[test]
pub fn test_term_set_query_fast_field_bool() -> crate::Result<()> {
let index = create_test_index()?;
let reader = index.reader()?;
let searcher = reader.searcher();
let bool_field_fast = index.schema().get_field("bool_fast").unwrap();
let query = FastFieldTermSetQuery::new(vec![Term::from_field_bool(bool_field_fast, true)]);
let count = searcher.search(&query, &Count)?;
assert_eq!(count, 2);
let query = FastFieldTermSetQuery::new(vec![Term::from_field_bool(bool_field_fast, false)]);
let count = searcher.search(&query, &Count)?;
assert_eq!(count, 1);
Ok(())
}
@@ -362,6 +392,10 @@ mod tests {
let count = searcher.search(&query, &Count)?;
assert_eq!(count, 2);
let query = query_parser.parse_query("bool_fast: IN [true]")?;
let count = searcher.search(&query, &Count)?;
assert_eq!(count, 2);
Ok(())
}