From eb292a7a62d63d986a689a84be557ea80e3c3dd9 Mon Sep 17 00:00:00 2001 From: Tamo Date: Wed, 26 Jun 2024 10:00:54 +0200 Subject: [PATCH] Fix the missing geo distance when one or both of the lat / lng are string --- meilisearch/src/search.rs | 62 ++++++++++++++++++++++++++++++++- meilisearch/tests/search/geo.rs | 3 +- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/meilisearch/src/search.rs b/meilisearch/src/search.rs index 0c2c49452..7f258b952 100644 --- a/meilisearch/src/search.rs +++ b/meilisearch/src/search.rs @@ -1150,13 +1150,23 @@ fn insert_geo_distance(sorts: &[String], document: &mut Document) { // TODO: TAMO: milli encountered an internal error, what do we want to do? let base = [capture_group[1].parse().unwrap(), capture_group[2].parse().unwrap()]; let geo_point = &document.get("_geo").unwrap_or(&json!(null)); - if let Some((lat, lng)) = geo_point["lat"].as_f64().zip(geo_point["lng"].as_f64()) { + if let Some((lat, lng)) = + extract_geo_value(&geo_point["lat"]).zip(extract_geo_value(&geo_point["lng"])) + { let distance = milli::distance_between_two_points(&base, &[lat, lng]); document.insert("_geoDistance".to_string(), json!(distance.round() as usize)); } } } +fn extract_geo_value(value: &Value) -> Option { + match value { + Value::Number(n) => n.as_f64(), + Value::String(s) => s.parse().ok(), + _ => None, + } +} + fn compute_formatted_options( attr_to_highlight: &HashSet, attr_to_crop: &[String], @@ -1530,4 +1540,54 @@ mod test { insert_geo_distance(sorters, &mut document); assert_eq!(document.get("_geoDistance"), None); } + + #[test] + fn test_insert_geo_distance_with_coords_as_string() { + let value: Document = serde_json::from_str( + r#"{ + "_geo": { + "lat": "50", + "lng": 3 + } + }"#, + ) + .unwrap(); + + let sorters = &["_geoPoint(50,3):desc".to_string()]; + let mut document = value.clone(); + insert_geo_distance(sorters, &mut document); + assert_eq!(document.get("_geoDistance"), Some(&json!(0))); + + let value: Document = serde_json::from_str( + r#"{ + "_geo": { + "lat": "50", + "lng": "3" + }, + "id": "1" + }"#, + ) + .unwrap(); + + let sorters = &["_geoPoint(50,3):desc".to_string()]; + let mut document = value.clone(); + insert_geo_distance(sorters, &mut document); + assert_eq!(document.get("_geoDistance"), Some(&json!(0))); + + let value: Document = serde_json::from_str( + r#"{ + "_geo": { + "lat": 50, + "lng": "3" + }, + "id": "1" + }"#, + ) + .unwrap(); + + let sorters = &["_geoPoint(50,3):desc".to_string()]; + let mut document = value.clone(); + insert_geo_distance(sorters, &mut document); + assert_eq!(document.get("_geoDistance"), Some(&json!(0))); + } } diff --git a/meilisearch/tests/search/geo.rs b/meilisearch/tests/search/geo.rs index 8754453ba..7804f1ad0 100644 --- a/meilisearch/tests/search/geo.rs +++ b/meilisearch/tests/search/geo.rs @@ -150,7 +150,8 @@ async fn bug_4640() { "_geo": { "lat": "45.4777599", "lng": "9.1967508" - } + }, + "_geoDistance": 0 }, { "id": 1,