Introduce linear scale instead of a unit one for scores

This commit is contained in:
Louis Dureuil 2023-06-08 16:52:18 +02:00
parent efc3371b6f
commit 4e740f4c5f
No known key found for this signature in database

View File

@ -38,6 +38,10 @@ impl ScoreDetails {
Rank::global_score(details.filter_map(Self::rank)) Rank::global_score(details.filter_map(Self::rank))
} }
pub fn global_score_linear_scale<'a>(details: impl Iterator<Item = &'a Self>) -> u64 {
(Self::global_score(details) * LINEAR_SCALE_FACTOR).round() as u64
}
/// Panics /// Panics
/// ///
/// - If Position is not preceded by Fid /// - If Position is not preceded by Fid
@ -55,7 +59,7 @@ impl ScoreDetails {
"order": order, "order": order,
"matchingWords": words.matching_words, "matchingWords": words.matching_words,
"maxMatchingWords": words.max_matching_words, "maxMatchingWords": words.max_matching_words,
"score": words.rank().local_score(), "score": words.rank().local_score_linear_scale(),
}); });
details_map.insert("words".into(), words_details); details_map.insert("words".into(), words_details);
order += 1; order += 1;
@ -65,7 +69,7 @@ impl ScoreDetails {
"order": order, "order": order,
"typoCount": typo.typo_count, "typoCount": typo.typo_count,
"maxTypoCount": typo.max_typo_count, "maxTypoCount": typo.max_typo_count,
"score": typo.rank().local_score(), "score": typo.rank().local_score_linear_scale(),
}); });
details_map.insert("typo".into(), typo_details); details_map.insert("typo".into(), typo_details);
order += 1; order += 1;
@ -73,7 +77,7 @@ impl ScoreDetails {
ScoreDetails::Proximity(proximity) => { ScoreDetails::Proximity(proximity) => {
let proximity_details = serde_json::json!({ let proximity_details = serde_json::json!({
"order": order, "order": order,
"score": proximity.local_score(), "score": proximity.local_score_linear_scale(),
}); });
details_map.insert("proximity".into(), proximity_details); details_map.insert("proximity".into(), proximity_details);
order += 1; order += 1;
@ -82,7 +86,7 @@ impl ScoreDetails {
// For now, fid is a virtual rule always followed by the "position" rule // For now, fid is a virtual rule always followed by the "position" rule
let fid_details = serde_json::json!({ let fid_details = serde_json::json!({
"order": order, "order": order,
"vertical_score": fid.local_score(), "attributes_ranking_order": fid.local_score_linear_scale(),
}); });
details_map.insert("attribute".into(), fid_details); details_map.insert("attribute".into(), fid_details);
order += 1; order += 1;
@ -95,15 +99,17 @@ impl ScoreDetails {
let attribute_details = attribute_details let attribute_details = attribute_details
.as_object_mut() .as_object_mut()
.expect("attribute details was not an object"); .expect("attribute details was not an object");
attribute_details attribute_details.insert(
.insert("horizontal_score".into(), position.local_score().into()); "attributes_query_word_order".into(),
position.local_score_linear_scale().into(),
);
// do not update the order since this was already done by fid // do not update the order since this was already done by fid
} }
ScoreDetails::ExactAttribute(exact_attribute) => { ScoreDetails::ExactAttribute(exact_attribute) => {
let exactness_details = serde_json::json!({ let exactness_details = serde_json::json!({
"order": order, "order": order,
"exactIn": exact_attribute, "exactIn": exact_attribute,
"score": exact_attribute.rank().local_score(), "score": exact_attribute.rank().local_score_linear_scale(),
}); });
details_map.insert("exactness".into(), exactness_details); details_map.insert("exactness".into(), exactness_details);
order += 1; order += 1;
@ -119,7 +125,7 @@ impl ScoreDetails {
if exactness_details.get("exactIn").expect("missing 'exactIn'") if exactness_details.get("exactIn").expect("missing 'exactIn'")
== &serde_json::json!(ExactAttribute::NoExactMatch) == &serde_json::json!(ExactAttribute::NoExactMatch)
{ {
let score = Rank::global_score( let score = Rank::global_score_linear_scale(
[ExactAttribute::NoExactMatch.rank(), *details].iter().copied(), [ExactAttribute::NoExactMatch.rank(), *details].iter().copied(),
); );
*exactness_details.get_mut("score").expect("missing score") = score.into(); *exactness_details.get_mut("score").expect("missing score") = score.into();
@ -225,6 +231,10 @@ impl Rank {
self.rank as f64 / self.max_rank as f64 self.rank as f64 / self.max_rank as f64
} }
pub fn local_score_linear_scale(self) -> u64 {
(self.local_score() * LINEAR_SCALE_FACTOR).round() as u64
}
pub fn global_score(details: impl Iterator<Item = Self>) -> f64 { pub fn global_score(details: impl Iterator<Item = Self>) -> f64 {
let mut rank = Rank { rank: 1, max_rank: 1 }; let mut rank = Rank { rank: 1, max_rank: 1 };
for inner_rank in details { for inner_rank in details {
@ -237,6 +247,10 @@ impl Rank {
} }
rank.local_score() rank.local_score()
} }
pub fn global_score_linear_scale(details: impl Iterator<Item = Self>) -> u64 {
(Self::global_score(details) * LINEAR_SCALE_FACTOR).round() as u64
}
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize)]
@ -277,3 +291,5 @@ impl GeoSort {
self.value.map(|value| distance_between_two_points(&self.target_point, &value)) self.value.map(|value| distance_between_two_points(&self.target_point, &value))
} }
} }
const LINEAR_SCALE_FACTOR: f64 = 1000.0;