caio.co/de/cantine

Add broad filters based on sort parameters

When sorting by a feature, only output recipes that actually contain
said feature.

I'm not sure I like this - In one hand the `items` part of the output
is a lot more sane, but it's really weird to ask for sorting and
having the result-set change drastically.

I think the ideal, albeit still very weird, is pushing the items
with missing features to the end of the results (i.e. score them
with MAX or MIN, based on order), but doing that externally will
be very annoying.
Id
e3250e5f08c4ea924e49d03d0784f947c21e1c68
Author
Caio
Commit time
2020-01-12T09:27:55+01:00

Modified cantine/src/main.rs

@@ -11,7 +11,7
};

use tantivy::{
- query::{AllQuery, BooleanQuery, Occur, Query},
+ query::{AllQuery, BooleanQuery, Occur, Query, RangeQuery},
Index, IndexReader, Result,
};

@@ -174,6 +174,35
if let Some(filter) = &query.filter {
for query in self.recipe_index.features.interpret(filter).into_iter() {
subqueries.push((Occur::Must, query));
+ }
+ }
+
+ macro_rules! max_range_bound {
+ ($type: ident, $range: ident, $field: ident) => {{
+ subqueries.push((
+ Occur::Must,
+ Box::new(RangeQuery::$range(
+ self.recipe_index.features.$field,
+ std::$type::MIN..std::$type::MAX,
+ )),
+ ))
+ }};
+ }
+
+ // Sorting by a feature implies filtering for recipes that actually
+ // contain said feature
+ if let Some(sort) = &query.sort {
+ match sort {
+ Sort::Relevance => {}
+ Sort::NumIngredients => max_range_bound!(u64, new_u64, num_ingredients),
+ Sort::InstructionsLength => max_range_bound!(u64, new_u64, instructions_length),
+ Sort::TotalTime => max_range_bound!(u64, new_u64, total_time),
+ Sort::CookTime => max_range_bound!(u64, new_u64, cook_time),
+ Sort::PrepTime => max_range_bound!(u64, new_u64, prep_time),
+ Sort::Calories => max_range_bound!(u64, new_u64, calories),
+ Sort::FatContent => max_range_bound!(f64, new_f64, fat_content),
+ Sort::CarbContent => max_range_bound!(f64, new_f64, carb_content),
+ Sort::ProteinContent => max_range_bound!(f64, new_f64, protein_content),
}
}