From c695a1ffd2306e663cf027d1727dca4e8c0c1503 Mon Sep 17 00:00:00 2001 From: Tamo Date: Mon, 13 Sep 2021 14:27:14 +0200 Subject: [PATCH] add the possibility to sort by descending order on geoPoint --- milli/src/search/criteria/geo.rs | 39 ++++++++++++++++++++++++++++---- milli/src/search/criteria/mod.rs | 15 ++++++------ 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/milli/src/search/criteria/geo.rs b/milli/src/search/criteria/geo.rs index 9629a4a15..de6de8912 100644 --- a/milli/src/search/criteria/geo.rs +++ b/milli/src/search/criteria/geo.rs @@ -10,6 +10,7 @@ use crate::{GeoPoint, Index, Result}; pub struct Geo<'t> { index: &'t Index, rtxn: &'t heed::RoTxn<'t>, + ascending: bool, parent: Box, candidates: Box>, allowed_candidates: RoaringBitmap, @@ -19,11 +20,30 @@ pub struct Geo<'t> { } impl<'t> Geo<'t> { - pub fn new( + pub fn asc( index: &'t Index, rtxn: &'t heed::RoTxn<'t>, parent: Box, point: [f64; 2], + ) -> Result { + Self::new(index, rtxn, parent, point, true) + } + + pub fn desc( + index: &'t Index, + rtxn: &'t heed::RoTxn<'t>, + parent: Box, + point: [f64; 2], + ) -> Result { + Self::new(index, rtxn, parent, point, false) + } + + fn new( + index: &'t Index, + rtxn: &'t heed::RoTxn<'t>, + parent: Box, + point: [f64; 2], + ascending: bool, ) -> Result { let candidates = Box::new(iter::empty()); let allowed_candidates = index.geo_faceted_documents_ids(rtxn)?; @@ -33,6 +53,7 @@ impl<'t> Geo<'t> { Ok(Self { index, rtxn, + ascending, parent, candidates, allowed_candidates, @@ -89,9 +110,12 @@ impl Criterion for Geo<'_> { } self.allowed_candidates = &candidates - params.excluded_candidates; self.candidates = match rtree { - Some(rtree) => { - geo_point(rtree, self.allowed_candidates.clone(), self.point) - } + Some(rtree) => geo_point( + rtree, + self.allowed_candidates.clone(), + self.point, + self.ascending, + ), None => Box::new(std::iter::empty()), }; } @@ -106,6 +130,7 @@ fn geo_point( rtree: &RTree, mut candidates: RoaringBitmap, point: [f64; 2], + ascending: bool, ) -> Box> { let mut results = Vec::new(); for point in rtree.nearest_neighbor_iter(&point) { @@ -117,5 +142,9 @@ fn geo_point( } } - Box::new(results.into_iter()) + if ascending { + Box::new(results.into_iter()) + } else { + Box::new(results.into_iter().rev()) + } } diff --git a/milli/src/search/criteria/mod.rs b/milli/src/search/criteria/mod.rs index 3c9485012..c2de55de5 100644 --- a/milli/src/search/criteria/mod.rs +++ b/milli/src/search/criteria/mod.rs @@ -15,7 +15,7 @@ use super::query_tree::{Operation, PrimitiveQueryPart, Query, QueryKind}; use crate::criterion::{AscDesc as AscDescName, Member}; use crate::search::criteria::geo::Geo; use crate::search::{word_derivations, WordDerivationsCache}; -use crate::{DocumentId, FieldId, Index, Result, TreeLevel, UserError}; +use crate::{DocumentId, FieldId, Index, Result, TreeLevel}; mod asc_desc; mod attribute; @@ -304,17 +304,18 @@ impl<'t> CriteriaBuilder<'t> { criterion, field.to_string(), )?), - AscDescName::Asc(Member::Geo(point)) => Box::new(Geo::new( + AscDescName::Asc(Member::Geo(point)) => Box::new(Geo::asc( + &self.index, + &self.rtxn, + criterion, + point.clone(), + )?), + AscDescName::Desc(Member::Geo(point)) => Box::new(Geo::desc( &self.index, &self.rtxn, criterion, point.clone(), )?), - AscDescName::Desc(Member::Geo(_point)) => { - return Err(UserError::InvalidSortName { - name: "sorting in descending order is not supported for the geosearch".to_string(), - })? - } }; } criterion