mirror of
https://github.com/meilisearch/MeiliSearch
synced 2024-11-26 23:04:26 +01:00
Merge pull request #400 from meilisearch/fix-issues
Close multiples issues on HTTP behavior
This commit is contained in:
commit
70f18a8086
@ -24,9 +24,7 @@ impl<'a> ser::Serializer for Indexer<'a> {
|
||||
type SerializeStructVariant = ser::Impossible<Self::Ok, Self::Error>;
|
||||
|
||||
fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerializerError::UnindexableType {
|
||||
type_name: "boolean",
|
||||
})
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn serialize_char(self, value: char) -> Result<Self::Ok, Self::Error> {
|
||||
@ -96,9 +94,7 @@ impl<'a> ser::Serializer for Indexer<'a> {
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerializerError::UnindexableType {
|
||||
type_name: "Option",
|
||||
})
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
|
||||
@ -113,13 +109,11 @@ impl<'a> ser::Serializer for Indexer<'a> {
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerializerError::UnindexableType { type_name: "()" })
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerializerError::UnindexableType {
|
||||
type_name: "unit struct",
|
||||
})
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
@ -128,9 +122,7 @@ impl<'a> ser::Serializer for Indexer<'a> {
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
Err(SerializerError::UnindexableType {
|
||||
type_name: "unit variant",
|
||||
})
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
@ -219,9 +211,14 @@ impl<'a> ser::Serializer for Indexer<'a> {
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
Err(SerializerError::UnindexableType {
|
||||
type_name: "struct",
|
||||
})
|
||||
let indexer = StructIndexer {
|
||||
attribute: self.attribute,
|
||||
document_id: self.document_id,
|
||||
indexer: self.indexer,
|
||||
texts: Vec::new(),
|
||||
};
|
||||
|
||||
Ok(indexer)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
|
@ -101,6 +101,8 @@ pub fn apply_stop_words_deletion(
|
||||
|
||||
// now that we have setup the stop words
|
||||
// lets reindex everything...
|
||||
if let Ok(number) = main_store.number_of_documents(writer) {
|
||||
if number > 0 {
|
||||
reindex_all_documents(
|
||||
writer,
|
||||
main_store,
|
||||
@ -109,6 +111,8 @@ pub fn apply_stop_words_deletion(
|
||||
postings_lists_store,
|
||||
docs_words_store,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ impl IntoResponse for ResponseError {
|
||||
error(err, StatusCode::BAD_REQUEST)
|
||||
}
|
||||
ResponseError::InvalidToken(err) => {
|
||||
error(format!("Invalid Token: {}", err), StatusCode::FORBIDDEN)
|
||||
error(format!("Invalid API key: {}", err), StatusCode::FORBIDDEN)
|
||||
}
|
||||
ResponseError::NotFound(err) => error(err, StatusCode::NOT_FOUND),
|
||||
ResponseError::IndexNotFound(index) => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::routes::setting::{RankingOrdering, SettingBody};
|
||||
use crate::routes::setting::{RankingOrdering, Setting};
|
||||
use indexmap::IndexMap;
|
||||
use log::error;
|
||||
use log::{error, warn};
|
||||
use meilisearch_core::criterion::*;
|
||||
use meilisearch_core::Highlight;
|
||||
use meilisearch_core::{Index, RankedMap};
|
||||
@ -243,7 +243,14 @@ impl<'a> SearchBuilder<'a> {
|
||||
.map_err(|e| Error::RetrieveDocument(doc.id.0, e.to_string()))?
|
||||
.ok_or(Error::DocumentNotFound(doc.id.0))?;
|
||||
|
||||
let mut formatted = document.clone();
|
||||
let has_attributes_to_highlight = self.attributes_to_highlight.is_some();
|
||||
let has_attributes_to_crop = self.attributes_to_crop.is_some();
|
||||
|
||||
let mut formatted = if has_attributes_to_highlight || has_attributes_to_crop {
|
||||
document.clone()
|
||||
} else {
|
||||
IndexMap::new()
|
||||
};
|
||||
let mut matches = doc.highlights.clone();
|
||||
|
||||
// Crops fields if needed
|
||||
@ -292,7 +299,7 @@ impl<'a> SearchBuilder<'a> {
|
||||
) -> Result<Option<Criteria<'a>>, Error> {
|
||||
let current_settings = match self.index.main.customs(reader).unwrap() {
|
||||
Some(bytes) => bincode::deserialize(bytes).unwrap(),
|
||||
None => SettingBody::default(),
|
||||
None => Setting::default(),
|
||||
};
|
||||
|
||||
let ranking_rules = ¤t_settings.ranking_rules;
|
||||
@ -342,13 +349,19 @@ impl<'a> SearchBuilder<'a> {
|
||||
for (rule, order) in ranking_rules.iter() {
|
||||
let custom_ranking = match order {
|
||||
RankingOrdering::Asc => {
|
||||
SortByAttr::lower_is_better(&ranked_map, &schema, &rule).unwrap()
|
||||
SortByAttr::lower_is_better(&ranked_map, &schema, &rule)
|
||||
}
|
||||
RankingOrdering::Dsc => {
|
||||
SortByAttr::higher_is_better(&ranked_map, &schema, &rule).unwrap()
|
||||
SortByAttr::higher_is_better(&ranked_map, &schema, &rule)
|
||||
}
|
||||
};
|
||||
if let Ok(custom_ranking) = custom_ranking {
|
||||
builder.push(custom_ranking);
|
||||
} else {
|
||||
// TODO push this warning to a log tree
|
||||
warn!("Custom ranking cannot be added; Attribute {} not registered for ranking", rule)
|
||||
}
|
||||
|
||||
}
|
||||
builder.push(DocumentId);
|
||||
return Ok(Some(builder.build()));
|
||||
@ -494,7 +507,7 @@ fn calculate_highlights(
|
||||
matches: &MatchesInfos,
|
||||
attributes_to_highlight: &HashSet<String>,
|
||||
) -> IndexMap<String, Value> {
|
||||
let mut highlight_result = IndexMap::new();
|
||||
let mut highlight_result = document.clone();
|
||||
|
||||
for (attribute, matches) in matches.iter() {
|
||||
if attributes_to_highlight.contains(attribute) {
|
||||
|
@ -66,7 +66,7 @@ impl ContextExt for Context<Data> {
|
||||
}
|
||||
|
||||
if !token_config.acl.contains(&acl) {
|
||||
return Err(ResponseError::invalid_token("token do not have this ACL"));
|
||||
return Err(ResponseError::invalid_token("no permission"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -390,19 +390,10 @@ pub async fn get_all_updates_status(ctx: Context<Data>) -> SResult<Response> {
|
||||
|
||||
pub async fn delete_index(ctx: Context<Data>) -> SResult<StatusCode> {
|
||||
ctx.is_allowed(IndexesWrite)?;
|
||||
let _ = ctx.index()?;
|
||||
let index_uid = ctx.url_param("index")?;
|
||||
|
||||
let found = ctx
|
||||
.state()
|
||||
.db
|
||||
.delete_index(&index_uid)
|
||||
.map_err(ResponseError::internal)?;
|
||||
|
||||
if found {
|
||||
ctx.state().db.delete_index(&index_uid).map_err(ResponseError::internal)?;
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
} else {
|
||||
Ok(StatusCode::NOT_FOUND)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use http::StatusCode;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde::{Deserialize, Serialize, Deserializer};
|
||||
use tide::response::IntoResponse;
|
||||
use tide::{Context, Response};
|
||||
|
||||
@ -11,9 +11,9 @@ use crate::models::token::ACL::*;
|
||||
use crate::routes::document::IndexUpdateResponse;
|
||||
use crate::Data;
|
||||
|
||||
#[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Default, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct SettingBody {
|
||||
pub struct Setting {
|
||||
pub ranking_order: Option<RankingOrder>,
|
||||
pub distinct_field: Option<DistinctField>,
|
||||
pub ranking_rules: Option<RankingRules>,
|
||||
@ -39,12 +39,31 @@ pub async fn get(ctx: Context<Data>) -> SResult<Response> {
|
||||
|
||||
let settings = match index.main.customs(&reader).unwrap() {
|
||||
Some(bytes) => bincode::deserialize(bytes).unwrap(),
|
||||
None => SettingBody::default(),
|
||||
None => Setting::default(),
|
||||
};
|
||||
|
||||
Ok(tide::response::json(settings))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
pub struct SettingBody {
|
||||
#[serde(default, deserialize_with = "deserialize_some")]
|
||||
pub ranking_order: Option<Option<RankingOrder>>,
|
||||
#[serde(default, deserialize_with = "deserialize_some")]
|
||||
pub distinct_field: Option<Option<DistinctField>>,
|
||||
#[serde(default, deserialize_with = "deserialize_some")]
|
||||
pub ranking_rules: Option<Option<RankingRules>>,
|
||||
}
|
||||
|
||||
// Any value that is present is considered Some value, including null.
|
||||
fn deserialize_some<'de, T, D>(deserializer: D) -> Result<Option<T>, D::Error>
|
||||
where T: Deserialize<'de>,
|
||||
D: Deserializer<'de>
|
||||
{
|
||||
Deserialize::deserialize(deserializer).map(Some)
|
||||
}
|
||||
|
||||
pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
||||
ctx.is_allowed(SettingsWrite)?;
|
||||
|
||||
@ -58,19 +77,19 @@ pub async fn update(mut ctx: Context<Data>) -> SResult<Response> {
|
||||
|
||||
let mut current_settings = match index.main.customs(&reader).unwrap() {
|
||||
Some(bytes) => bincode::deserialize(bytes).unwrap(),
|
||||
None => SettingBody::default(),
|
||||
None => Setting::default(),
|
||||
};
|
||||
|
||||
if let Some(ranking_order) = settings.ranking_order {
|
||||
current_settings.ranking_order = Some(ranking_order);
|
||||
current_settings.ranking_order = ranking_order;
|
||||
}
|
||||
|
||||
if let Some(distinct_field) = settings.distinct_field {
|
||||
current_settings.distinct_field = Some(distinct_field);
|
||||
current_settings.distinct_field = distinct_field;
|
||||
}
|
||||
|
||||
if let Some(ranking_rules) = settings.ranking_rules {
|
||||
current_settings.ranking_rules = Some(ranking_rules);
|
||||
current_settings.ranking_rules = ranking_rules;
|
||||
}
|
||||
|
||||
let bytes = bincode::serialize(¤t_settings).unwrap();
|
||||
|
Loading…
Reference in New Issue
Block a user