diff --git a/Cargo.lock b/Cargo.lock index ccf79f9a2..effdfe9a7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2731,6 +2731,7 @@ dependencies = [ "grenad", "heed", "hnsw", + "indexmap", "insta", "itertools", "json-depth-checker", diff --git a/meilisearch/Cargo.toml b/meilisearch/Cargo.toml index d90dd24dd..7d6601ac5 100644 --- a/meilisearch/Cargo.toml +++ b/meilisearch/Cargo.toml @@ -14,14 +14,27 @@ default-run = "meilisearch" [dependencies] actix-cors = "0.6.4" -actix-http = { version = "3.3.1", default-features = false, features = ["compress-brotli", "compress-gzip", "rustls"] } -actix-web = { version = "4.3.1", default-features = false, features = ["macros", "compress-brotli", "compress-gzip", "cookies", "rustls"] } +actix-http = { version = "3.3.1", default-features = false, features = [ + "compress-brotli", + "compress-gzip", + "rustls", +] } +actix-web = { version = "4.3.1", default-features = false, features = [ + "macros", + "compress-brotli", + "compress-gzip", + "cookies", + "rustls", +] } actix-web-static-files = { git = "https://github.com/kilork/actix-web-static-files.git", rev = "2d3b6160", optional = true } anyhow = { version = "1.0.70", features = ["backtrace"] } async-stream = "0.3.5" async-trait = "0.1.68" bstr = "1.4.0" -byte-unit = { version = "4.0.19", default-features = false, features = ["std", "serde"] } +byte-unit = { version = "4.0.19", default-features = false, features = [ + "std", + "serde", +] } bytes = "1.4.0" clap = { version = "4.2.1", features = ["derive", "env"] } crossbeam-channel = "0.5.8" @@ -57,7 +70,10 @@ prometheus = { version = "0.13.3", features = ["process"] } rand = "0.8.5" rayon = "1.7.0" regex = "1.7.3" -reqwest = { version = "0.11.16", features = ["rustls-tls", "json"], default-features = false } +reqwest = { version = "0.11.16", features = [ + "rustls-tls", + "json", +], default-features = false } rustls = "0.20.8" rustls-pemfile = "1.0.2" segment = { version = "0.2.2", optional = true } @@ -71,7 +87,12 @@ sysinfo = "0.28.4" tar = "0.4.38" tempfile = "3.5.0" thiserror = "1.0.40" -time = { version = "0.3.20", features = ["serde-well-known", "formatting", "parsing", "macros"] } +time = { version = "0.3.20", features = [ + "serde-well-known", + "formatting", + "parsing", + "macros", +] } tokio = { version = "1.27.0", features = ["full"] } tokio-stream = "0.1.12" toml = "0.7.3" @@ -90,7 +111,7 @@ brotli = "3.3.4" insta = "1.29.0" manifest-dir-macros = "0.1.16" maplit = "1.0.2" -meili-snap = {path = "../meili-snap"} +meili-snap = { path = "../meili-snap" } temp-env = "0.3.3" urlencoding = "2.1.2" yaup = "0.2.1" @@ -99,7 +120,10 @@ yaup = "0.2.1" anyhow = { version = "1.0.70", optional = true } cargo_toml = { version = "0.15.2", optional = true } hex = { version = "0.4.3", optional = true } -reqwest = { version = "0.11.16", features = ["blocking", "rustls-tls"], default-features = false, optional = true } +reqwest = { version = "0.11.16", features = [ + "blocking", + "rustls-tls", +], default-features = false, optional = true } sha-1 = { version = "0.10.1", optional = true } static-files = { version = "0.2.3", optional = true } tempfile = { version = "3.5.0", optional = true } @@ -109,7 +133,17 @@ zip = { version = "0.6.4", optional = true } [features] default = ["analytics", "meilisearch-types/all-tokenizations", "mini-dashboard"] analytics = ["segment"] -mini-dashboard = ["actix-web-static-files", "static-files", "anyhow", "cargo_toml", "hex", "reqwest", "sha-1", "tempfile", "zip"] +mini-dashboard = [ + "actix-web-static-files", + "static-files", + "anyhow", + "cargo_toml", + "hex", + "reqwest", + "sha-1", + "tempfile", + "zip", +] chinese = ["meilisearch-types/chinese"] hebrew = ["meilisearch-types/hebrew"] japanese = ["meilisearch-types/japanese"] diff --git a/meilisearch/src/search.rs b/meilisearch/src/search.rs index ed2378d94..21a2a4312 100644 --- a/meilisearch/src/search.rs +++ b/meilisearch/src/search.rs @@ -6,6 +6,7 @@ use std::time::Instant; use deserr::Deserr; use either::Either; use index_scheduler::RoFeatures; +use indexmap::IndexMap; use log::warn; use meilisearch_auth::IndexSearchRules; use meilisearch_types::deserr::DeserrJsonError; @@ -279,7 +280,7 @@ pub struct SearchResult { #[serde(flatten)] pub hits_info: HitsInfo, #[serde(skip_serializing_if = "Option::is_none")] - pub facet_distribution: Option>>, + pub facet_distribution: Option>>, #[serde(skip_serializing_if = "Option::is_none")] pub facet_stats: Option>, } diff --git a/milli/Cargo.toml b/milli/Cargo.toml index 08f0c2645..aa4b98ec2 100644 --- a/milli/Cargo.toml +++ b/milli/Cargo.toml @@ -34,6 +34,7 @@ heed = { git = "https://github.com/meilisearch/heed", tag = "v0.12.6", default-f "sync-read-txn", ] } hnsw = { version = "0.11.0", features = ["serde1"] } +indexmap = { version = "1.9.3", features = ["serde"] } json-depth-checker = { path = "../json-depth-checker" } levenshtein_automata = { version = "0.2.1", features = ["fst_automaton"] } memmap2 = "0.5.10" diff --git a/milli/src/search/facet/facet_distribution.rs b/milli/src/search/facet/facet_distribution.rs index 3cc970049..f49cbe1c4 100644 --- a/milli/src/search/facet/facet_distribution.rs +++ b/milli/src/search/facet/facet_distribution.rs @@ -4,6 +4,7 @@ use std::{fmt, mem}; use heed::types::ByteSlice; use heed::BytesDecode; +use indexmap::IndexMap; use roaring::RoaringBitmap; use crate::error::UserError; @@ -83,7 +84,7 @@ impl<'a> FacetDistribution<'a> { field_id: FieldId, facet_type: FacetType, candidates: &RoaringBitmap, - distribution: &mut BTreeMap, + distribution: &mut IndexMap, ) -> heed::Result<()> { match facet_type { FacetType::Number => { @@ -153,7 +154,7 @@ impl<'a> FacetDistribution<'a> { field_id: FieldId, candidates: &RoaringBitmap, order_by: OrderBy, - distribution: &mut BTreeMap, + distribution: &mut IndexMap, ) -> heed::Result<()> { let search_function = match order_by { OrderBy::Lexicographic => lexicographically_iterate_over_facet_distribution, @@ -184,7 +185,7 @@ impl<'a> FacetDistribution<'a> { field_id: FieldId, candidates: &RoaringBitmap, order_by: OrderBy, - distribution: &mut BTreeMap, + distribution: &mut IndexMap, ) -> heed::Result<()> { let search_function = match order_by { OrderBy::Lexicographic => lexicographically_iterate_over_facet_distribution, @@ -219,10 +220,10 @@ impl<'a> FacetDistribution<'a> { ) } - fn facet_values(&self, field_id: FieldId) -> heed::Result> { + fn facet_values(&self, field_id: FieldId) -> heed::Result> { use FacetType::{Number, String}; - let mut distribution = BTreeMap::new(); + let mut distribution = IndexMap::new(); match (self.order_by, &self.candidates) { (OrderBy::Lexicographic, Some(cnd)) if cnd.len() <= CANDIDATES_THRESHOLD => { // Classic search, candidates were specified, we must return facet values only related @@ -318,7 +319,7 @@ impl<'a> FacetDistribution<'a> { Ok(distribution) } - pub fn execute(&self) -> Result>> { + pub fn execute(&self) -> Result>> { let fields_ids_map = self.index.fields_ids_map(self.rtxn)?; let filterable_fields = self.index.filterable_fields(self.rtxn)?;