Revert metadata creation when computing the facet-distribution

This commit is contained in:
ManyTheFish 2025-03-10 17:05:41 +01:00
parent abef655849
commit 40c5f911fd
5 changed files with 85 additions and 93 deletions

View file

@ -121,10 +121,10 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco
and can not be more than 511 bytes.", .document_id.to_string()
)]
InvalidDocumentId { document_id: Value },
#[error("Invalid facet distribution, {}", format_invalid_filter_distribution(.invalid_facets_name, .valid_facets_name))]
#[error("Invalid facet distribution, {}", format_invalid_filter_distribution(.invalid_facets_name, .valid_patterns))]
InvalidFacetsDistribution {
invalid_facets_name: BTreeSet<String>,
valid_facets_name: BTreeSet<String>,
valid_patterns: BTreeSet<String>,
},
#[error(transparent)]
InvalidGeoField(#[from] GeoError),
@ -357,9 +357,9 @@ pub enum GeoError {
fn format_invalid_filter_distribution(
invalid_facets_name: &BTreeSet<String>,
valid_facets_name: &BTreeSet<String>,
valid_patterns: &BTreeSet<String>,
) -> String {
if valid_facets_name.is_empty() {
if valid_patterns.is_empty() {
return "this index does not have configured filterable attributes.".into();
}
@ -381,17 +381,17 @@ fn format_invalid_filter_distribution(
.unwrap(),
};
match valid_facets_name.len() {
match valid_patterns.len() {
1 => write!(
result,
" The available filterable attribute is `{}`.",
valid_facets_name.first().unwrap()
" The available filterable attribute pattern is `{}`.",
valid_patterns.first().unwrap()
)
.unwrap(),
_ => write!(
result,
" The available filterable attributes are `{}`.",
valid_facets_name.iter().map(AsRef::as_ref).collect::<Vec<&str>>().join(", ")
" The available filterable attribute patterns are `{}`.",
valid_patterns.iter().map(AsRef::as_ref).collect::<Vec<&str>>().join(", ")
)
.unwrap(),
}

View file

@ -11,7 +11,7 @@ use serde::{Deserialize, Serialize};
use crate::attribute_patterns::match_field_legacy;
use crate::facet::FacetType;
use crate::fields_ids_map::metadata::{FieldIdMapWithMetadata, Metadata, MetadataBuilder};
use crate::filterable_attributes_rules::{filtered_matching_patterns, matching_features};
use crate::heed_codec::facet::{
FacetGroupKeyCodec, FieldDocIdFacetF64Codec, FieldDocIdFacetStringCodec, OrderedF64Codec,
};
@ -294,13 +294,13 @@ impl<'a> FacetDistribution<'a> {
return Ok(Default::default());
};
let fields_ids_map = self.index.fields_ids_map_with_metadata(self.rtxn)?;
let fields_ids_map = self.index.fields_ids_map(self.rtxn)?;
let filterable_attributes_rules = self.index.filterable_attributes_rules(self.rtxn)?;
self.check_faceted_fields(&fields_ids_map, &filterable_attributes_rules)?;
self.check_faceted_fields(&filterable_attributes_rules)?;
let mut distribution = BTreeMap::new();
for (fid, name, metadata) in fields_ids_map.iter() {
if self.select_field(name, &metadata, &filterable_attributes_rules) {
for (fid, name) in fields_ids_map.iter() {
if self.select_field(name, &filterable_attributes_rules) {
let min_value = if let Some(min_value) = crate::search::facet::facet_min_value(
self.index,
self.rtxn,
@ -331,16 +331,12 @@ impl<'a> FacetDistribution<'a> {
pub fn execute(&self) -> Result<BTreeMap<String, IndexMap<String, u64>>> {
let fields_ids_map = self.index.fields_ids_map(self.rtxn)?;
let fields_ids_map = FieldIdMapWithMetadata::new(
fields_ids_map,
MetadataBuilder::from_index(self.index, self.rtxn)?,
);
let filterable_attributes_rules = self.index.filterable_attributes_rules(self.rtxn)?;
self.check_faceted_fields(&fields_ids_map, &filterable_attributes_rules)?;
self.check_faceted_fields(&filterable_attributes_rules)?;
let mut distribution = BTreeMap::new();
for (fid, name, metadata) in fields_ids_map.iter() {
if self.select_field(name, &metadata, &filterable_attributes_rules) {
for (fid, name) in fields_ids_map.iter() {
if self.select_field(name, &filterable_attributes_rules) {
let order_by = self
.facets
.as_ref()
@ -358,11 +354,12 @@ impl<'a> FacetDistribution<'a> {
fn select_field(
&self,
name: &str,
metadata: &Metadata,
filterable_attributes_rules: &[FilterableAttributesRule],
) -> bool {
// If the field is not filterable, we don't want to compute the facet distribution.
if !metadata.filterable_attributes_features(filterable_attributes_rules).is_filterable() {
if !matching_features(name, filterable_attributes_rules)
.map_or(false, |(_, features)| features.is_filterable())
{
return false;
}
@ -378,41 +375,31 @@ impl<'a> FacetDistribution<'a> {
/// Check if the fields in the facets are valid faceted fields.
fn check_faceted_fields(
&self,
fields_ids_map: &FieldIdMapWithMetadata,
filterable_attributes_rules: &[FilterableAttributesRule],
) -> Result<()> {
let mut invalid_facets = BTreeSet::new();
if let Some(facets) = &self.facets {
for field in facets.keys() {
let is_valid_faceted_field =
fields_ids_map.id_with_metadata(field).map_or(false, |(_, metadata)| {
metadata
.filterable_attributes_features(filterable_attributes_rules)
.is_filterable()
});
if !is_valid_faceted_field {
let is_valid_filterable_field =
matching_features(field, filterable_attributes_rules)
.map_or(false, |(_, features)| features.is_filterable());
if !is_valid_filterable_field {
invalid_facets.insert(field.to_string());
}
}
}
if !invalid_facets.is_empty() {
let valid_facets_name = fields_ids_map
.iter()
.filter_map(|(_, name, metadata)| {
if metadata
.filterable_attributes_features(filterable_attributes_rules)
.is_filterable()
{
Some(name.to_string())
} else {
None
}
let valid_patterns =
filtered_matching_patterns(filterable_attributes_rules, &|features| {
features.is_filterable()
})
.into_iter()
.map(String::from)
.collect();
return Err(Error::UserError(UserError::InvalidFacetsDistribution {
invalid_facets_name: invalid_facets,
valid_facets_name,
valid_patterns,
}));
}