From e0f73fe7427a961b2a1b52d713a6f85ebb876042 Mon Sep 17 00:00:00 2001 From: Kerollmops Date: Tue, 24 Aug 2021 12:31:35 +0200 Subject: [PATCH] Introduce the sort search parameter --- meilisearch-http/src/index/search.rs | 14 +++++++++++++- meilisearch-http/src/routes/indexes/search.rs | 16 ++++++++++------ 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/meilisearch-http/src/index/search.rs b/meilisearch-http/src/index/search.rs index 620178773..4fd7f8cd1 100644 --- a/meilisearch-http/src/index/search.rs +++ b/meilisearch-http/src/index/search.rs @@ -1,15 +1,17 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; +use std::str::FromStr; use std::time::Instant; use either::Either; use heed::RoTxn; use indexmap::IndexMap; use meilisearch_tokenizer::{Analyzer, AnalyzerConfig, Token}; -use milli::{FieldId, FieldsIdsMap, FilterCondition, MatchingWords}; +use milli::{AscDesc, FieldId, FieldsIdsMap, FilterCondition, MatchingWords}; use serde::{Deserialize, Serialize}; use serde_json::Value; use crate::index::error::FacetError; +use crate::index::IndexError; use super::error::Result; use super::Index; @@ -49,6 +51,7 @@ pub struct SearchQuery { #[serde(default = "Default::default")] pub matches: bool, pub filter: Option, + pub sort: Option>, pub facets_distribution: Option>, } @@ -104,6 +107,15 @@ impl Index { } } + if let Some(ref sort) = query.sort { + let sort = match sort.iter().map(|s| AscDesc::from_str(s)).collect() { + Ok(sorts) => sorts, + Err(err) => return Err(IndexError::Milli(err.into())), + }; + + search.sort_criteria(sort); + } + let milli::SearchResult { documents_ids, matching_words, diff --git a/meilisearch-http/src/routes/indexes/search.rs b/meilisearch-http/src/routes/indexes/search.rs index 8a2f4ae1d..83f58648e 100644 --- a/meilisearch-http/src/routes/indexes/search.rs +++ b/meilisearch-http/src/routes/indexes/search.rs @@ -1,5 +1,3 @@ -use std::collections::{BTreeSet, HashSet}; - use actix_web::{web, HttpResponse}; use log::debug; use serde::Deserialize; @@ -31,6 +29,7 @@ pub struct SearchQueryGet { crop_length: usize, attributes_to_highlight: Option, filter: Option, + sort: Option, #[serde(default = "Default::default")] matches: bool, facets_distribution: Option, @@ -40,19 +39,19 @@ impl From for SearchQuery { fn from(other: SearchQueryGet) -> Self { let attributes_to_retrieve = other .attributes_to_retrieve - .map(|attrs| attrs.split(',').map(String::from).collect::>()); + .map(|attrs| attrs.split(',').map(String::from).collect()); let attributes_to_crop = other .attributes_to_crop - .map(|attrs| attrs.split(',').map(String::from).collect::>()); + .map(|attrs| attrs.split(',').map(String::from).collect()); let attributes_to_highlight = other .attributes_to_highlight - .map(|attrs| attrs.split(',').map(String::from).collect::>()); + .map(|attrs| attrs.split(',').map(String::from).collect()); let facets_distribution = other .facets_distribution - .map(|attrs| attrs.split(',').map(String::from).collect::>()); + .map(|attrs| attrs.split(',').map(String::from).collect()); let filter = match other.filter { Some(f) => match serde_json::from_str(&f) { @@ -62,6 +61,10 @@ impl From for SearchQuery { None => None, }; + let sort = other + .sort + .map(|attrs| attrs.split(',').map(String::from).collect()); + Self { q: other.q, offset: other.offset, @@ -71,6 +74,7 @@ impl From for SearchQuery { crop_length: other.crop_length, attributes_to_highlight, filter, + sort, matches: other.matches, facets_distribution, }