Merge pull request #400 from meilisearch/fix-issues

Close multiples issues on HTTP behavior
This commit is contained in:
Clément Renault 2019-12-13 10:30:42 +01:00 committed by GitHub
commit 70f18a8086
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 54 deletions

View File

@ -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(

View File

@ -101,14 +101,18 @@ pub fn apply_stop_words_deletion(
// now that we have setup the stop words
// lets reindex everything...
reindex_all_documents(
writer,
main_store,
documents_fields_store,
documents_fields_counts_store,
postings_lists_store,
docs_words_store,
)?;
if let Ok(number) = main_store.number_of_documents(writer) {
if number > 0 {
reindex_all_documents(
writer,
main_store,
documents_fields_store,
documents_fields_counts_store,
postings_lists_store,
docs_words_store,
)?;
}
}
Ok(())
}

View File

@ -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) => {

View File

@ -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 = &current_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)
}
};
builder.push(custom_ranking);
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) {

View File

@ -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(())

View File

@ -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 {
Ok(StatusCode::NO_CONTENT)
} else {
Ok(StatusCode::NOT_FOUND)
}
ctx.state().db.delete_index(&index_uid).map_err(ResponseError::internal)?;
Ok(StatusCode::NO_CONTENT)
}
pub fn index_update_callback(index_uid: &str, data: &Data, status: ProcessedUpdateResult) {

View File

@ -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(&current_settings).unwrap();