diff --git a/crates/meilisearch/src/routes/chat.rs b/crates/meilisearch/src/routes/chat.rs
index d2fe4ee3a..1cc5f1012 100644
--- a/crates/meilisearch/src/routes/chat.rs
+++ b/crates/meilisearch/src/routes/chat.rs
@@ -29,7 +29,7 @@ use meilisearch_auth::AuthController;
use meilisearch_types::error::ResponseError;
use meilisearch_types::heed::RoTxn;
use meilisearch_types::keys::actions;
-use meilisearch_types::milli::index::{self, ChatConfig, SearchParameters};
+use meilisearch_types::milli::index::ChatConfig;
use meilisearch_types::milli::prompt::{Prompt, PromptData};
use meilisearch_types::milli::update::new::document::DocumentFromDb;
use meilisearch_types::milli::update::Setting;
@@ -50,11 +50,7 @@ use crate::extractors::authentication::policies::ActionPolicy;
use crate::extractors::authentication::{extract_token_from_request, GuardedData, Policy as _};
use crate::metrics::MEILISEARCH_DEGRADED_SEARCH_REQUESTS;
use crate::routes::indexes::search::search_kind;
-use crate::search::{
- add_search_rules, prepare_search, search_from_kind, HybridQuery, MatchingStrategy,
- RankingScoreThreshold, SearchQuery, SemanticRatio, DEFAULT_SEARCH_LIMIT,
- DEFAULT_SEMANTIC_RATIO,
-};
+use crate::search::{add_search_rules, prepare_search, search_from_kind, SearchQuery};
use crate::search_queue::SearchQueue;
const MEILI_SEARCH_PROGRESS_NAME: &str = "_meiliSearchProgress";
@@ -228,40 +224,7 @@ async fn process_search_request(
let index = index_scheduler.index(&index_uid)?;
let rtxn = index.static_read_txn()?;
let ChatConfig { description: _, prompt: _, search_parameters } = index.chat_config(&rtxn)?;
- let SearchParameters {
- hybrid,
- limit,
- sort,
- distinct,
- matching_strategy,
- attributes_to_search_on,
- ranking_score_threshold,
- } = search_parameters;
-
- let mut query = SearchQuery {
- q,
- hybrid: hybrid.map(|index::HybridQuery { semantic_ratio, embedder }| HybridQuery {
- semantic_ratio: SemanticRatio::try_from(semantic_ratio)
- .ok()
- .unwrap_or_else(DEFAULT_SEMANTIC_RATIO),
- embedder,
- }),
- limit: limit.unwrap_or_else(DEFAULT_SEARCH_LIMIT),
- sort,
- distinct,
- matching_strategy: matching_strategy
- .map(|ms| match ms {
- index::MatchingStrategy::Last => MatchingStrategy::Last,
- index::MatchingStrategy::All => MatchingStrategy::All,
- index::MatchingStrategy::Frequency => MatchingStrategy::Frequency,
- })
- .unwrap_or(MatchingStrategy::Frequency),
- attributes_to_search_on,
- ranking_score_threshold: ranking_score_threshold
- .and_then(|rst| RankingScoreThreshold::try_from(rst).ok()),
- ..Default::default()
- };
-
+ let mut query = SearchQuery { q, ..SearchQuery::from(search_parameters) };
let auth_filter = ActionPolicy::<{ actions::SEARCH }>::authenticate(
auth_ctrl,
auth_token,
diff --git a/crates/meilisearch/src/search/mod.rs b/crates/meilisearch/src/search/mod.rs
index 848591a4f..037083b2d 100644
--- a/crates/meilisearch/src/search/mod.rs
+++ b/crates/meilisearch/src/search/mod.rs
@@ -16,6 +16,7 @@ use meilisearch_types::error::{Code, ResponseError};
use meilisearch_types::heed::RoTxn;
use meilisearch_types::index_uid::IndexUid;
use meilisearch_types::locales::Locale;
+use meilisearch_types::milli::index::{self, SearchParameters};
use meilisearch_types::milli::score_details::{ScoreDetails, ScoringStrategy};
use meilisearch_types::milli::vector::parsed_vectors::ExplicitVectors;
use meilisearch_types::milli::vector::Embedder;
@@ -56,7 +57,7 @@ pub const DEFAULT_HIGHLIGHT_PRE_TAG: fn() -> String = || "".to_string();
pub const DEFAULT_HIGHLIGHT_POST_TAG: fn() -> String = || "".to_string();
pub const DEFAULT_SEMANTIC_RATIO: fn() -> SemanticRatio = || SemanticRatio(0.5);
-#[derive(Clone, Default, PartialEq, Deserr, ToSchema)]
+#[derive(Clone, PartialEq, Deserr, ToSchema)]
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
pub struct SearchQuery {
#[deserr(default, error = DeserrJsonError)]
@@ -119,6 +120,69 @@ pub struct SearchQuery {
pub locales: Option>,
}
+impl From for SearchQuery {
+ fn from(parameters: SearchParameters) -> Self {
+ let SearchParameters {
+ hybrid,
+ limit,
+ sort,
+ distinct,
+ matching_strategy,
+ attributes_to_search_on,
+ ranking_score_threshold,
+ } = parameters;
+
+ SearchQuery {
+ hybrid: hybrid.map(|index::HybridQuery { semantic_ratio, embedder }| HybridQuery {
+ semantic_ratio: SemanticRatio::try_from(semantic_ratio)
+ .ok()
+ .unwrap_or_else(DEFAULT_SEMANTIC_RATIO),
+ embedder,
+ }),
+ limit: limit.unwrap_or_else(DEFAULT_SEARCH_LIMIT),
+ sort,
+ distinct,
+ matching_strategy: matching_strategy.map(MatchingStrategy::from).unwrap_or_default(),
+ attributes_to_search_on,
+ ranking_score_threshold: ranking_score_threshold.map(RankingScoreThreshold::from),
+ ..Default::default()
+ }
+ }
+}
+
+impl Default for SearchQuery {
+ fn default() -> Self {
+ SearchQuery {
+ q: None,
+ vector: None,
+ hybrid: None,
+ offset: DEFAULT_SEARCH_OFFSET(),
+ limit: DEFAULT_SEARCH_LIMIT(),
+ page: None,
+ hits_per_page: None,
+ attributes_to_retrieve: None,
+ retrieve_vectors: false,
+ attributes_to_crop: None,
+ crop_length: DEFAULT_CROP_LENGTH(),
+ attributes_to_highlight: None,
+ show_matches_position: false,
+ show_ranking_score: false,
+ show_ranking_score_details: false,
+ filter: None,
+ sort: None,
+ distinct: None,
+ facets: None,
+ highlight_pre_tag: DEFAULT_HIGHLIGHT_PRE_TAG(),
+ highlight_post_tag: DEFAULT_HIGHLIGHT_POST_TAG(),
+ crop_marker: DEFAULT_CROP_MARKER(),
+ matching_strategy: Default::default(),
+ attributes_to_search_on: None,
+ ranking_score_threshold: None,
+ locales: None,
+ }
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Deserr, ToSchema, Serialize)]
#[deserr(try_from(f64) = TryFrom::try_from -> InvalidSearchRankingScoreThreshold)]
pub struct RankingScoreThreshold(f64);
@@ -137,6 +201,14 @@ impl std::convert::TryFrom for RankingScoreThreshold {
}
}
+impl From for RankingScoreThreshold {
+ fn from(threshold: index::RankingScoreThreshold) -> Self {
+ let threshold = threshold.as_f64();
+ assert!(threshold >= 0.0 && threshold <= 1.0);
+ RankingScoreThreshold(threshold)
+ }
+}
+
#[derive(Debug, Clone, Copy, PartialEq, Deserr)]
#[deserr(try_from(f64) = TryFrom::try_from -> InvalidSimilarRankingScoreThreshold)]
pub struct RankingScoreThresholdSimilar(f64);
@@ -718,6 +790,16 @@ impl From for TermsMatchingStrategy {
}
}
+impl From for MatchingStrategy {
+ fn from(other: index::MatchingStrategy) -> Self {
+ match other {
+ index::MatchingStrategy::Last => Self::Last,
+ index::MatchingStrategy::All => Self::All,
+ index::MatchingStrategy::Frequency => Self::Frequency,
+ }
+ }
+}
+
#[derive(Debug, Default, Clone, PartialEq, Eq, Deserr)]
#[deserr(rename_all = camelCase)]
pub enum FacetValuesSort {
@@ -1261,7 +1343,7 @@ struct HitMaker<'a> {
vectors_fid: Option,
retrieve_vectors: RetrieveVectors,
to_retrieve_ids: BTreeSet,
- embedding_configs: Vec,
+ embedding_configs: Vec,
formatter_builder: MatcherBuilder<'a>,
formatted_options: BTreeMap,
show_ranking_score: bool,
diff --git a/crates/milli/src/index.rs b/crates/milli/src/index.rs
index e6f28d02e..b2df46af3 100644
--- a/crates/milli/src/index.rs
+++ b/crates/milli/src/index.rs
@@ -1,14 +1,18 @@
use std::borrow::Cow;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
+use std::error::Error;
+use std::fmt;
use std::fs::File;
use std::path::Path;
+use deserr::Deserr;
use heed::types::*;
use heed::{CompactionOption, Database, DatabaseStat, RoTxn, RwTxn, Unspecified, WithoutTls};
use indexmap::IndexMap;
use roaring::RoaringBitmap;
use rstar::RTree;
use serde::{Deserialize, Serialize};
+use utoipa::ToSchema;
use crate::constants::{self, RESERVED_GEO_FIELD_NAME, RESERVED_VECTORS_FIELD_NAME};
use crate::database_stats::DatabaseStats;
@@ -25,6 +29,7 @@ use crate::heed_codec::{BEU16StrCodec, FstSetCodec, StrBEU16Codec, StrRefCodec};
use crate::order_by_map::OrderByMap;
use crate::prompt::PromptData;
use crate::proximity::ProximityPrecision;
+use crate::update::new::StdResult;
use crate::vector::{ArroyStats, ArroyWrapper, Embedding, EmbeddingConfig};
use crate::{
default_criteria, CboRoaringBitmapCodec, Criterion, DocumentId, ExternalDocumentsIds,
@@ -1962,10 +1967,46 @@ pub struct SearchParameters {
#[serde(skip_serializing_if = "Option::is_none")]
pub attributes_to_search_on: Option>,
#[serde(skip_serializing_if = "Option::is_none")]
- pub ranking_score_threshold: Option,
+ pub ranking_score_threshold: Option,
}
-#[derive(Debug, Default, Deserialize, Serialize)]
+#[derive(Debug, Clone, Copy, Default, Deserialize, Serialize, PartialEq, Deserr, ToSchema)]
+#[deserr(try_from(f64) = TryFrom::try_from -> InvalidSearchRankingScoreThreshold)]
+pub struct RankingScoreThreshold(f64);
+
+impl RankingScoreThreshold {
+ pub fn as_f64(&self) -> f64 {
+ self.0
+ }
+}
+
+impl TryFrom for RankingScoreThreshold {
+ type Error = InvalidSearchRankingScoreThreshold;
+
+ fn try_from(value: f64) -> StdResult {
+ if value < 0.0 || value > 1.0 {
+ Err(InvalidSearchRankingScoreThreshold)
+ } else {
+ Ok(RankingScoreThreshold(value))
+ }
+ }
+}
+
+#[derive(Debug)]
+pub struct InvalidSearchRankingScoreThreshold;
+
+impl Error for InvalidSearchRankingScoreThreshold {}
+
+impl fmt::Display for InvalidSearchRankingScoreThreshold {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "the value of `rankingScoreThreshold` is invalid, expected a float between `0.0` and `1.0`."
+ )
+ }
+}
+
+#[derive(Debug, Clone, Default, Deserialize, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct HybridQuery {
pub semantic_ratio: f32,
@@ -1980,10 +2021,12 @@ pub struct PrefixSettings {
pub compute_prefixes: PrefixSearch,
}
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
+#[derive(Default, Debug, Copy, Clone, PartialEq, Eq, Deserr, ToSchema, Serialize, Deserialize)]
+#[deserr(rename_all = camelCase)]
#[serde(rename_all = "camelCase")]
pub enum MatchingStrategy {
/// Remove query words from last to first
+ #[default]
Last,
/// All query words are mandatory
All,
diff --git a/crates/milli/src/prompt/mod.rs b/crates/milli/src/prompt/mod.rs
index d40fcd27f..a8288f83d 100644
--- a/crates/milli/src/prompt/mod.rs
+++ b/crates/milli/src/prompt/mod.rs
@@ -64,7 +64,7 @@ fn default_template() -> liquid::Template {
new_template(default_template_text()).unwrap()
}
-fn default_template_text() -> &'static str {
+pub fn default_template_text() -> &'static str {
"{% for field in fields %}\
{% if field.is_searchable and field.value != nil %}\
{{ field.name }}: {{ field.value }}\n\
diff --git a/crates/milli/src/search/mod.rs b/crates/milli/src/search/mod.rs
index 37b1aaf09..62183afc3 100644
--- a/crates/milli/src/search/mod.rs
+++ b/crates/milli/src/search/mod.rs
@@ -10,6 +10,7 @@ pub use self::facet::{FacetDistribution, Filter, OrderBy, DEFAULT_VALUES_PER_FAC
pub use self::new::matches::{FormatOptions, MatchBounds, MatcherBuilder, MatchingWords};
use self::new::{execute_vector_search, PartialSearchResult, VectorStoreStats};
use crate::filterable_attributes_rules::{filtered_matching_patterns, matching_features};
+use crate::index::MatchingStrategy;
use crate::score_details::{ScoreDetails, ScoringStrategy};
use crate::vector::Embedder;
use crate::{
@@ -364,6 +365,16 @@ impl Default for TermsMatchingStrategy {
}
}
+impl From for TermsMatchingStrategy {
+ fn from(other: MatchingStrategy) -> Self {
+ match other {
+ MatchingStrategy::Last => Self::Last,
+ MatchingStrategy::All => Self::All,
+ MatchingStrategy::Frequency => Self::Frequency,
+ }
+ }
+}
+
fn get_first(s: &str) -> &str {
match s.chars().next() {
Some(c) => &s[..c.len_utf8()],
diff --git a/crates/milli/src/update/chat.rs b/crates/milli/src/update/chat.rs
index b8fbc582d..ae95ddfd9 100644
--- a/crates/milli/src/update/chat.rs
+++ b/crates/milli/src/update/chat.rs
@@ -6,10 +6,9 @@ use deserr::Deserr;
use serde::{Deserialize, Serialize};
use utoipa::ToSchema;
-use crate::index::{self, ChatConfig, SearchParameters};
+use crate::index::{self, ChatConfig, MatchingStrategy, RankingScoreThreshold, SearchParameters};
use crate::prompt::{default_max_bytes, PromptData};
use crate::update::Setting;
-use crate::TermsMatchingStrategy;
#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Deserr, ToSchema)]
#[serde(deny_unknown_fields, rename_all = "camelCase")]
@@ -70,13 +69,10 @@ impl From for ChatSettings {
HybridQuery { semantic_ratio: SemanticRatio(semantic_ratio), embedder }
});
- let matching_strategy = matching_strategy.map(|ms| match ms {
- index::MatchingStrategy::Last => MatchingStrategy::Last,
- index::MatchingStrategy::All => MatchingStrategy::All,
- index::MatchingStrategy::Frequency => MatchingStrategy::Frequency,
- });
+ let matching_strategy = matching_strategy.map(MatchingStrategy::from);
- let ranking_score_threshold = ranking_score_threshold.map(RankingScoreThreshold);
+ let ranking_score_threshold =
+ ranking_score_threshold.map(RankingScoreThreshold::from);
ChatSearchParams {
hybrid: Setting::some_or_not_set(hybrid),
@@ -197,63 +193,3 @@ impl std::ops::Deref for SemanticRatio {
&self.0
}
}
-
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Deserr, ToSchema, Serialize, Deserialize)]
-#[deserr(rename_all = camelCase)]
-#[serde(rename_all = "camelCase")]
-pub enum MatchingStrategy {
- /// Remove query words from last to first
- Last,
- /// All query words are mandatory
- All,
- /// Remove query words from the most frequent to the least
- Frequency,
-}
-
-impl Default for MatchingStrategy {
- fn default() -> Self {
- Self::Last
- }
-}
-
-impl From for TermsMatchingStrategy {
- fn from(other: MatchingStrategy) -> Self {
- match other {
- MatchingStrategy::Last => Self::Last,
- MatchingStrategy::All => Self::All,
- MatchingStrategy::Frequency => Self::Frequency,
- }
- }
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Deserr, ToSchema, Serialize, Deserialize)]
-#[deserr(try_from(f64) = TryFrom::try_from -> InvalidSearchRankingScoreThreshold)]
-pub struct RankingScoreThreshold(pub f64);
-
-impl std::convert::TryFrom for RankingScoreThreshold {
- type Error = InvalidSearchRankingScoreThreshold;
-
- fn try_from(f: f64) -> Result {
- // the suggested "fix" is: `!(0.0..=1.0).contains(&f)`` which is allegedly less readable
- #[allow(clippy::manual_range_contains)]
- if f > 1.0 || f < 0.0 {
- Err(InvalidSearchRankingScoreThreshold)
- } else {
- Ok(RankingScoreThreshold(f))
- }
- }
-}
-
-#[derive(Debug)]
-pub struct InvalidSearchRankingScoreThreshold;
-
-impl Error for InvalidSearchRankingScoreThreshold {}
-
-impl fmt::Display for InvalidSearchRankingScoreThreshold {
- fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
- write!(
- f,
- "the value of `rankingScoreThreshold` is invalid, expected a float between `0.0` and `1.0`."
- )
- }
-}
diff --git a/crates/milli/src/update/settings.rs b/crates/milli/src/update/settings.rs
index bb589c5ee..9f152710a 100644
--- a/crates/milli/src/update/settings.rs
+++ b/crates/milli/src/update/settings.rs
@@ -11,7 +11,7 @@ use roaring::RoaringBitmap;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use time::OffsetDateTime;
-use super::chat::{ChatSearchParams, RankingScoreThreshold};
+use super::chat::ChatSearchParams;
use super::del_add::{DelAdd, DelAddOperation};
use super::index_documents::{IndexDocumentsConfig, Transform};
use super::{ChatSettings, IndexerConfig};
@@ -23,11 +23,11 @@ use crate::error::UserError;
use crate::fields_ids_map::metadata::{FieldIdMapWithMetadata, MetadataBuilder};
use crate::filterable_attributes_rules::match_faceted_field;
use crate::index::{
- ChatConfig, IndexEmbeddingConfig, MatchingStrategy, PrefixSearch,
- DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS,
+ ChatConfig, IndexEmbeddingConfig, MatchingStrategy, PrefixSearch, RankingScoreThreshold,
+ SearchParameters, DEFAULT_MIN_WORD_LEN_ONE_TYPO, DEFAULT_MIN_WORD_LEN_TWO_TYPOS,
};
use crate::order_by_map::OrderByMap;
-use crate::prompt::{default_max_bytes, PromptData};
+use crate::prompt::{default_max_bytes, default_template_text, PromptData};
use crate::proximity::ProximityPrecision;
use crate::update::index_documents::IndexDocumentsMethod;
use crate::update::{IndexDocuments, UpdateIndexingStep};
@@ -1266,32 +1266,29 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> {
document_template_max_bytes: new_document_template_max_bytes,
search_parameters: new_search_parameters,
}) => {
- let mut old = self.index.chat_config(self.wtxn)?;
- let ChatConfig {
- ref mut description,
- prompt: PromptData { ref mut template, ref mut max_bytes },
- ref mut search_parameters,
- } = old;
+ let ChatConfig { description, prompt, search_parameters } =
+ self.index.chat_config(self.wtxn)?;
- match new_description {
- Setting::Set(d) => *description = d.clone(),
- Setting::Reset => *description = Default::default(),
- Setting::NotSet => (),
- }
+ let description = match new_description {
+ Setting::Set(new) => new.clone(),
+ Setting::Reset => Default::default(),
+ Setting::NotSet => description,
+ };
- match new_document_template {
- Setting::Set(dt) => *template = dt.clone(),
- Setting::Reset => *template = Default::default(),
- Setting::NotSet => (),
- }
+ let prompt = PromptData {
+ template: match new_document_template {
+ Setting::Set(new) => new.clone(),
+ Setting::Reset => default_template_text().to_string(),
+ Setting::NotSet => prompt.template.clone(),
+ },
+ max_bytes: match new_document_template_max_bytes {
+ Setting::Set(m) => NonZeroUsize::new(*m),
+ Setting::Reset => Some(default_max_bytes()),
+ Setting::NotSet => prompt.max_bytes,
+ },
+ };
- match new_document_template_max_bytes {
- Setting::Set(m) => *max_bytes = NonZeroUsize::new(*m),
- Setting::Reset => *max_bytes = Some(default_max_bytes()),
- Setting::NotSet => (),
- }
-
- match new_search_parameters {
+ let search_parameters = match new_search_parameters {
Setting::Set(sp) => {
let ChatSearchParams {
hybrid,
@@ -1303,74 +1300,62 @@ impl<'a, 't, 'i> Settings<'a, 't, 'i> {
ranking_score_threshold,
} = sp;
- match hybrid {
- Setting::Set(hybrid) => {
- search_parameters.hybrid = Some(crate::index::HybridQuery {
+ SearchParameters {
+ hybrid: match hybrid {
+ Setting::Set(hybrid) => Some(crate::index::HybridQuery {
semantic_ratio: *hybrid.semantic_ratio,
embedder: hybrid.embedder.clone(),
- })
- }
- Setting::Reset => search_parameters.hybrid = None,
- Setting::NotSet => (),
- }
-
- match limit {
- Setting::Set(limit) => search_parameters.limit = Some(*limit),
- Setting::Reset => search_parameters.limit = None,
- Setting::NotSet => (),
- }
-
- match sort {
- Setting::Set(sort) => search_parameters.sort = Some(sort.clone()),
- Setting::Reset => search_parameters.sort = None,
- Setting::NotSet => (),
- }
-
- match distinct {
- Setting::Set(distinct) => {
- search_parameters.distinct = Some(distinct.clone())
- }
- Setting::Reset => search_parameters.distinct = None,
- Setting::NotSet => (),
- }
-
- match matching_strategy {
- Setting::Set(matching_strategy) => {
- let strategy = match matching_strategy {
- super::chat::MatchingStrategy::Last => MatchingStrategy::Last,
- super::chat::MatchingStrategy::All => MatchingStrategy::All,
- super::chat::MatchingStrategy::Frequency => {
- MatchingStrategy::Frequency
- }
- };
- search_parameters.matching_strategy = Some(strategy)
- }
- Setting::Reset => search_parameters.matching_strategy = None,
- Setting::NotSet => (),
- }
-
- match attributes_to_search_on {
- Setting::Set(attributes_to_search_on) => {
- search_parameters.attributes_to_search_on =
+ }),
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.hybrid.clone(),
+ },
+ limit: match limit {
+ Setting::Set(limit) => Some(*limit),
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.limit,
+ },
+ sort: match sort {
+ Setting::Set(sort) => Some(sort.clone()),
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.sort.clone(),
+ },
+ distinct: match distinct {
+ Setting::Set(distinct) => Some(distinct.clone()),
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.distinct.clone(),
+ },
+ matching_strategy: match matching_strategy {
+ Setting::Set(matching_strategy) => {
+ Some(MatchingStrategy::from(*matching_strategy))
+ }
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.matching_strategy,
+ },
+ attributes_to_search_on: match attributes_to_search_on {
+ Setting::Set(attributes_to_search_on) => {
Some(attributes_to_search_on.clone())
- }
- Setting::Reset => search_parameters.attributes_to_search_on = None,
- Setting::NotSet => (),
- }
-
- match ranking_score_threshold {
- Setting::Set(RankingScoreThreshold(score)) => {
- search_parameters.ranking_score_threshold = Some(*score)
- }
- Setting::Reset => search_parameters.ranking_score_threshold = None,
- Setting::NotSet => (),
+ }
+ Setting::Reset => None,
+ Setting::NotSet => {
+ search_parameters.attributes_to_search_on.clone()
+ }
+ },
+ ranking_score_threshold: match ranking_score_threshold {
+ Setting::Set(rst) => Some(RankingScoreThreshold::from(*rst)),
+ Setting::Reset => None,
+ Setting::NotSet => search_parameters.ranking_score_threshold,
+ },
}
}
- Setting::Reset => *search_parameters = Default::default(),
- Setting::NotSet => (),
- }
+ Setting::Reset => Default::default(),
+ Setting::NotSet => search_parameters,
+ };
+
+ self.index.put_chat_config(
+ self.wtxn,
+ &ChatConfig { description, prompt, search_parameters },
+ )?;
- self.index.put_chat_config(self.wtxn, &old)?;
Ok(true)
}
Setting::Reset => self.index.delete_chat_config(self.wtxn),
diff --git a/crates/milli/src/update/test_settings.rs b/crates/milli/src/update/test_settings.rs
index e775c226f..e78765cfb 100644
--- a/crates/milli/src/update/test_settings.rs
+++ b/crates/milli/src/update/test_settings.rs
@@ -926,6 +926,7 @@ fn test_correct_settings_init() {
assert!(matches!(prefix_search, Setting::NotSet));
assert!(matches!(facet_search, Setting::NotSet));
assert!(matches!(disable_on_numbers, Setting::NotSet));
+ assert!(matches!(chat, Setting::NotSet));
})
.unwrap();
}