mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-04-18 07:57:59 +02:00
Merge branch 'add-index-name-to-sort-error-message' of github.com:cisco877/meilisearch into add-index-name-to-sort-error-message
This commit is contained in:
commit
0f7a004ac9
@ -634,6 +634,7 @@ impl SearchAggregator {
|
|||||||
pub fn from_query(query: &SearchQuery, request: &HttpRequest) -> Self {
|
pub fn from_query(query: &SearchQuery, request: &HttpRequest) -> Self {
|
||||||
let SearchQuery {
|
let SearchQuery {
|
||||||
q,
|
q,
|
||||||
|
index_uid,
|
||||||
vector,
|
vector,
|
||||||
offset,
|
offset,
|
||||||
limit,
|
limit,
|
||||||
|
@ -102,6 +102,7 @@ impl From<FacetSearchQuery> for SearchQuery {
|
|||||||
|
|
||||||
SearchQuery {
|
SearchQuery {
|
||||||
q,
|
q,
|
||||||
|
index_uid: None,
|
||||||
offset: DEFAULT_SEARCH_OFFSET(),
|
offset: DEFAULT_SEARCH_OFFSET(),
|
||||||
limit: DEFAULT_SEARCH_LIMIT(),
|
limit: DEFAULT_SEARCH_LIMIT(),
|
||||||
page: None,
|
page: None,
|
||||||
|
@ -128,6 +128,7 @@ impl From<SearchQueryGet> for SearchQuery {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
|
index_uid: None,
|
||||||
q: other.q,
|
q: other.q,
|
||||||
vector: other.vector.map(CS::into_inner),
|
vector: other.vector.map(CS::into_inner),
|
||||||
offset: other.offset.0,
|
offset: other.offset.0,
|
||||||
@ -203,8 +204,9 @@ pub async fn search_with_url_query(
|
|||||||
|
|
||||||
let distribution = embed(&mut query, index_scheduler.get_ref(), &index).await?;
|
let distribution = embed(&mut query, index_scheduler.get_ref(), &index).await?;
|
||||||
|
|
||||||
let search_result =
|
let search_result = tokio::task::spawn_blocking(move || {
|
||||||
tokio::task::spawn_blocking(move || perform_search(&index, query, features, distribution))
|
perform_search(&index, index_uid.to_string(), query, features, distribution)
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
if let Ok(ref search_result) = search_result {
|
if let Ok(ref search_result) = search_result {
|
||||||
aggregate.succeed(search_result);
|
aggregate.succeed(search_result);
|
||||||
@ -242,8 +244,9 @@ pub async fn search_with_post(
|
|||||||
|
|
||||||
let distribution = embed(&mut query, index_scheduler.get_ref(), &index).await?;
|
let distribution = embed(&mut query, index_scheduler.get_ref(), &index).await?;
|
||||||
|
|
||||||
let search_result =
|
let search_result = tokio::task::spawn_blocking(move || {
|
||||||
tokio::task::spawn_blocking(move || perform_search(&index, query, features, distribution))
|
perform_search(&index, index_uid.to_string(), query, features, distribution)
|
||||||
|
})
|
||||||
.await?;
|
.await?;
|
||||||
if let Ok(ref search_result) = search_result {
|
if let Ok(ref search_result) = search_result {
|
||||||
aggregate.succeed(search_result);
|
aggregate.succeed(search_result);
|
||||||
|
@ -54,6 +54,8 @@ pub async fn multi_search_with_post(
|
|||||||
{
|
{
|
||||||
debug!(on_index = query_index, parameters = ?query, "Multi-search");
|
debug!(on_index = query_index, parameters = ?query, "Multi-search");
|
||||||
|
|
||||||
|
let index_uid_name = &index_uid.clone();
|
||||||
|
|
||||||
// Check index from API key
|
// Check index from API key
|
||||||
if !index_scheduler.filters().is_index_authorized(&index_uid) {
|
if !index_scheduler.filters().is_index_authorized(&index_uid) {
|
||||||
return Err(AuthenticationError::InvalidToken).with_index(query_index);
|
return Err(AuthenticationError::InvalidToken).with_index(query_index);
|
||||||
@ -80,13 +82,13 @@ pub async fn multi_search_with_post(
|
|||||||
.with_index(query_index)?;
|
.with_index(query_index)?;
|
||||||
|
|
||||||
let search_result = tokio::task::spawn_blocking(move || {
|
let search_result = tokio::task::spawn_blocking(move || {
|
||||||
perform_search(&index, query, features, distribution)
|
perform_search(&index, index_uid.to_string().clone(), query, features, distribution)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.with_index(query_index)?;
|
.with_index(query_index)?;
|
||||||
|
|
||||||
search_results.push(SearchResultWithIndex {
|
search_results.push(SearchResultWithIndex {
|
||||||
index_uid: index_uid.into_inner(),
|
index_uid: index_uid_name.to_string(),
|
||||||
result: search_result.with_index(query_index)?,
|
result: search_result.with_index(query_index)?,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ pub const DEFAULT_SEMANTIC_RATIO: fn() -> SemanticRatio = || SemanticRatio(0.5);
|
|||||||
#[derive(Debug, Clone, Default, PartialEq, Deserr)]
|
#[derive(Debug, Clone, Default, PartialEq, Deserr)]
|
||||||
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrJsonError, rename_all = camelCase, deny_unknown_fields)]
|
||||||
pub struct SearchQuery {
|
pub struct SearchQuery {
|
||||||
|
pub index_uid: Option<String>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchQ>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchQ>)]
|
||||||
pub q: Option<String>,
|
pub q: Option<String>,
|
||||||
#[deserr(default, error = DeserrJsonError<InvalidSearchVector>)]
|
#[deserr(default, error = DeserrJsonError<InvalidSearchVector>)]
|
||||||
@ -192,6 +193,7 @@ pub struct SearchQueryWithIndex {
|
|||||||
|
|
||||||
impl SearchQueryWithIndex {
|
impl SearchQueryWithIndex {
|
||||||
pub fn into_index_query(self) -> (IndexUid, SearchQuery) {
|
pub fn into_index_query(self) -> (IndexUid, SearchQuery) {
|
||||||
|
let index_uid_name = self.index_uid.clone().to_string().clone();
|
||||||
let SearchQueryWithIndex {
|
let SearchQueryWithIndex {
|
||||||
index_uid,
|
index_uid,
|
||||||
q,
|
q,
|
||||||
@ -221,6 +223,7 @@ impl SearchQueryWithIndex {
|
|||||||
index_uid,
|
index_uid,
|
||||||
SearchQuery {
|
SearchQuery {
|
||||||
q,
|
q,
|
||||||
|
index_uid: Some(index_uid_name),
|
||||||
vector,
|
vector,
|
||||||
offset,
|
offset,
|
||||||
limit,
|
limit,
|
||||||
@ -378,12 +381,13 @@ pub fn add_search_rules(query: &mut SearchQuery, rules: IndexSearchRules) {
|
|||||||
|
|
||||||
fn prepare_search<'t>(
|
fn prepare_search<'t>(
|
||||||
index: &'t Index,
|
index: &'t Index,
|
||||||
|
index_uid: &String,
|
||||||
rtxn: &'t RoTxn,
|
rtxn: &'t RoTxn,
|
||||||
query: &'t SearchQuery,
|
query: &'t SearchQuery,
|
||||||
features: RoFeatures,
|
features: RoFeatures,
|
||||||
distribution: Option<DistributionShift>,
|
distribution: Option<DistributionShift>,
|
||||||
) -> Result<(milli::Search<'t>, bool, usize, usize), MeilisearchHttpError> {
|
) -> Result<(milli::Search<'t>, bool, usize, usize), MeilisearchHttpError> {
|
||||||
let mut search = index.search(rtxn);
|
let mut search = index.search(rtxn, index_uid.clone());
|
||||||
|
|
||||||
if query.vector.is_some() {
|
if query.vector.is_some() {
|
||||||
features.check_vector("Passing `vector` as a query parameter")?;
|
features.check_vector("Passing `vector` as a query parameter")?;
|
||||||
@ -486,6 +490,7 @@ fn prepare_search<'t>(
|
|||||||
|
|
||||||
pub fn perform_search(
|
pub fn perform_search(
|
||||||
index: &Index,
|
index: &Index,
|
||||||
|
index_uid: String,
|
||||||
query: SearchQuery,
|
query: SearchQuery,
|
||||||
features: RoFeatures,
|
features: RoFeatures,
|
||||||
distribution: Option<DistributionShift>,
|
distribution: Option<DistributionShift>,
|
||||||
@ -494,7 +499,7 @@ pub fn perform_search(
|
|||||||
let rtxn = index.read_txn()?;
|
let rtxn = index.read_txn()?;
|
||||||
|
|
||||||
let (search, is_finite_pagination, max_total_hits, offset) =
|
let (search, is_finite_pagination, max_total_hits, offset) =
|
||||||
prepare_search(index, &rtxn, &query, features, distribution)?;
|
prepare_search(index, &index_uid, &rtxn, &query, features, distribution)?;
|
||||||
|
|
||||||
let milli::SearchResult { documents_ids, matching_words, candidates, document_scores, .. } =
|
let milli::SearchResult { documents_ids, matching_words, candidates, document_scores, .. } =
|
||||||
match &query.hybrid {
|
match &query.hybrid {
|
||||||
@ -725,7 +730,8 @@ pub fn perform_facet_search(
|
|||||||
let before_search = Instant::now();
|
let before_search = Instant::now();
|
||||||
let rtxn = index.read_txn()?;
|
let rtxn = index.read_txn()?;
|
||||||
|
|
||||||
let (search, _, _, _) = prepare_search(index, &rtxn, &search_query, features, None)?;
|
let (search, _, _, _) =
|
||||||
|
prepare_search(index, &"".to_string(), &rtxn, &search_query, features, None)?;
|
||||||
let mut facet_search =
|
let mut facet_search =
|
||||||
SearchForFacetValues::new(facet_name, search, search_query.hybrid.is_some());
|
SearchForFacetValues::new(facet_name, search, search_query.hybrid.is_some());
|
||||||
if let Some(facet_query) = &facet_query {
|
if let Some(facet_query) = &facet_query {
|
||||||
|
@ -122,8 +122,9 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco
|
|||||||
InvalidFilter(String),
|
InvalidFilter(String),
|
||||||
#[error("Invalid type for filter subexpression: expected: {}, found: {1}.", .0.join(", "))]
|
#[error("Invalid type for filter subexpression: expected: {}, found: {1}.", .0.join(", "))]
|
||||||
InvalidFilterExpression(&'static [&'static str], Value),
|
InvalidFilterExpression(&'static [&'static str], Value),
|
||||||
#[error("Attribute `{}` is not sortable. {}",
|
#[error("Attribute `{}` of index `{}` is not sortable. {}",
|
||||||
.field,
|
.field,
|
||||||
|
.index,
|
||||||
match .valid_fields.is_empty() {
|
match .valid_fields.is_empty() {
|
||||||
true => "This index does not have configured sortable attributes.".to_string(),
|
true => "This index does not have configured sortable attributes.".to_string(),
|
||||||
false => format!("Available sortable attributes are: `{}{}`.",
|
false => format!("Available sortable attributes are: `{}{}`.",
|
||||||
@ -132,7 +133,7 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
InvalidSortableAttribute { field: String, valid_fields: BTreeSet<String>, hidden_fields: bool },
|
InvalidSortableAttribute { field: String, index: String, valid_fields: BTreeSet<String>, hidden_fields: bool },
|
||||||
#[error("Attribute `{}` is not facet-searchable. {}",
|
#[error("Attribute `{}` is not facet-searchable. {}",
|
||||||
.field,
|
.field,
|
||||||
match .valid_fields.is_empty() {
|
match .valid_fields.is_empty() {
|
||||||
|
@ -1212,8 +1212,8 @@ impl Index {
|
|||||||
FacetDistribution::new(rtxn, self)
|
FacetDistribution::new(rtxn, self)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn search<'a>(&'a self, rtxn: &'a RoTxn) -> Search<'a> {
|
pub fn search<'a>(&'a self, rtxn: &'a RoTxn, index_uid: String) -> Search<'a> {
|
||||||
Search::new(rtxn, self)
|
Search::new(rtxn, self, index_uid)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the index creation time.
|
/// Returns the index creation time.
|
||||||
|
@ -115,6 +115,7 @@ impl<'a> Search<'a> {
|
|||||||
// TODO: find classier way to achieve that than to reset vector and query params
|
// TODO: find classier way to achieve that than to reset vector and query params
|
||||||
// create separate keyword and semantic searches
|
// create separate keyword and semantic searches
|
||||||
let mut search = Search {
|
let mut search = Search {
|
||||||
|
index_uid: self.index_uid.to_string().clone(),
|
||||||
query: self.query.clone(),
|
query: self.query.clone(),
|
||||||
vector: self.vector.clone(),
|
vector: self.vector.clone(),
|
||||||
filter: self.filter.clone(),
|
filter: self.filter.clone(),
|
||||||
|
@ -36,6 +36,7 @@ pub mod hybrid;
|
|||||||
pub mod new;
|
pub mod new;
|
||||||
|
|
||||||
pub struct Search<'a> {
|
pub struct Search<'a> {
|
||||||
|
index_uid: String,
|
||||||
query: Option<String>,
|
query: Option<String>,
|
||||||
vector: Option<Vec<f32>>,
|
vector: Option<Vec<f32>>,
|
||||||
// this should be linked to the String in the query
|
// this should be linked to the String in the query
|
||||||
@ -57,8 +58,9 @@ pub struct Search<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Search<'a> {
|
impl<'a> Search<'a> {
|
||||||
pub fn new(rtxn: &'a heed::RoTxn, index: &'a Index) -> Search<'a> {
|
pub fn new(rtxn: &'a heed::RoTxn, index: &'a Index, index_uid: String) -> Search<'a> {
|
||||||
Search {
|
Search {
|
||||||
|
index_uid,
|
||||||
query: None,
|
query: None,
|
||||||
vector: None,
|
vector: None,
|
||||||
filter: None,
|
filter: None,
|
||||||
@ -156,7 +158,7 @@ impl<'a> Search<'a> {
|
|||||||
|
|
||||||
pub fn execute_for_candidates(&self, has_vector_search: bool) -> Result<RoaringBitmap> {
|
pub fn execute_for_candidates(&self, has_vector_search: bool) -> Result<RoaringBitmap> {
|
||||||
if has_vector_search {
|
if has_vector_search {
|
||||||
let ctx = SearchContext::new(self.index, self.rtxn);
|
let ctx = SearchContext::new(self.index, self.index_uid.to_string(), self.rtxn);
|
||||||
filtered_universe(&ctx, &self.filter)
|
filtered_universe(&ctx, &self.filter)
|
||||||
} else {
|
} else {
|
||||||
Ok(self.execute()?.candidates)
|
Ok(self.execute()?.candidates)
|
||||||
@ -173,7 +175,7 @@ impl<'a> Search<'a> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut ctx = SearchContext::new(self.index, self.rtxn);
|
let mut ctx = SearchContext::new(self.index, self.index_uid.to_string(), self.rtxn);
|
||||||
|
|
||||||
if let Some(searchable_attributes) = self.searchable_attributes {
|
if let Some(searchable_attributes) = self.searchable_attributes {
|
||||||
ctx.searchable_attributes(searchable_attributes)?;
|
ctx.searchable_attributes(searchable_attributes)?;
|
||||||
@ -224,6 +226,7 @@ impl<'a> Search<'a> {
|
|||||||
impl fmt::Debug for Search<'_> {
|
impl fmt::Debug for Search<'_> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let Search {
|
let Search {
|
||||||
|
index_uid,
|
||||||
query,
|
query,
|
||||||
vector: _,
|
vector: _,
|
||||||
filter,
|
filter,
|
||||||
@ -242,6 +245,7 @@ impl fmt::Debug for Search<'_> {
|
|||||||
embedder_name,
|
embedder_name,
|
||||||
} = self;
|
} = self;
|
||||||
f.debug_struct("Search")
|
f.debug_struct("Search")
|
||||||
|
.field("index_uid", index_uid)
|
||||||
.field("query", query)
|
.field("query", query)
|
||||||
.field("vector", &"[...]")
|
.field("vector", &"[...]")
|
||||||
.field("filter", filter)
|
.field("filter", filter)
|
||||||
|
@ -58,6 +58,7 @@ use crate::{
|
|||||||
/// A structure used throughout the execution of a search query.
|
/// A structure used throughout the execution of a search query.
|
||||||
pub struct SearchContext<'ctx> {
|
pub struct SearchContext<'ctx> {
|
||||||
pub index: &'ctx Index,
|
pub index: &'ctx Index,
|
||||||
|
pub index_uid: String,
|
||||||
pub txn: &'ctx RoTxn<'ctx>,
|
pub txn: &'ctx RoTxn<'ctx>,
|
||||||
pub db_cache: DatabaseCache<'ctx>,
|
pub db_cache: DatabaseCache<'ctx>,
|
||||||
pub word_interner: DedupInterner<String>,
|
pub word_interner: DedupInterner<String>,
|
||||||
@ -68,9 +69,10 @@ pub struct SearchContext<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'ctx> SearchContext<'ctx> {
|
impl<'ctx> SearchContext<'ctx> {
|
||||||
pub fn new(index: &'ctx Index, txn: &'ctx RoTxn<'ctx>) -> Self {
|
pub fn new(index: &'ctx Index, index_uid: String, txn: &'ctx RoTxn<'ctx>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
index,
|
index,
|
||||||
|
index_uid,
|
||||||
txn,
|
txn,
|
||||||
db_cache: <_>::default(),
|
db_cache: <_>::default(),
|
||||||
word_interner: <_>::default(),
|
word_interner: <_>::default(),
|
||||||
@ -706,6 +708,7 @@ fn check_sort_criteria(ctx: &SearchContext, sort_criteria: Option<&Vec<AscDesc>>
|
|||||||
|
|
||||||
return Err(UserError::InvalidSortableAttribute {
|
return Err(UserError::InvalidSortableAttribute {
|
||||||
field: field.to_string(),
|
field: field.to_string(),
|
||||||
|
index: ctx.index_uid.clone(),
|
||||||
valid_fields,
|
valid_fields,
|
||||||
hidden_fields,
|
hidden_fields,
|
||||||
}
|
}
|
||||||
@ -717,6 +720,7 @@ fn check_sort_criteria(ctx: &SearchContext, sort_criteria: Option<&Vec<AscDesc>>
|
|||||||
|
|
||||||
return Err(UserError::InvalidSortableAttribute {
|
return Err(UserError::InvalidSortableAttribute {
|
||||||
field: "_geo".to_string(),
|
field: "_geo".to_string(),
|
||||||
|
index: ctx.index_uid.clone(),
|
||||||
valid_fields,
|
valid_fields,
|
||||||
hidden_fields,
|
hidden_fields,
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user