2020-04-22 17:43:51 +02:00
|
|
|
use actix_web::{web, HttpResponse};
|
|
|
|
use actix_web_macros::{delete, get, post};
|
2020-02-26 18:24:19 +01:00
|
|
|
use meilisearch_core::settings::{Settings, SettingsUpdate, UpdateState, DEFAULT_RANKING_RULES};
|
2020-01-23 11:30:18 +01:00
|
|
|
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
2019-10-31 15:00:36 +01:00
|
|
|
|
2020-05-22 12:03:57 +02:00
|
|
|
use crate::error::{Error, ResponseError};
|
2020-04-22 17:43:51 +02:00
|
|
|
use crate::helpers::Authentication;
|
2020-04-10 19:05:05 +02:00
|
|
|
use crate::routes::{IndexParam, IndexUpdateResponse};
|
2019-10-31 15:00:36 +01:00
|
|
|
use crate::Data;
|
2020-04-09 11:11:48 +02:00
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
pub fn services(cfg: &mut web::ServiceConfig) {
|
|
|
|
cfg.service(update_all)
|
|
|
|
.service(get_all)
|
|
|
|
.service(delete_all)
|
|
|
|
.service(get_rules)
|
|
|
|
.service(update_rules)
|
|
|
|
.service(delete_rules)
|
|
|
|
.service(get_distinct)
|
|
|
|
.service(update_distinct)
|
|
|
|
.service(delete_distinct)
|
|
|
|
.service(get_searchable)
|
|
|
|
.service(update_searchable)
|
|
|
|
.service(delete_searchable)
|
|
|
|
.service(get_displayed)
|
|
|
|
.service(update_displayed)
|
|
|
|
.service(delete_displayed)
|
|
|
|
.service(get_accept_new_fields)
|
2020-06-03 10:24:58 +02:00
|
|
|
.service(update_accept_new_fields)
|
|
|
|
.service(get_attributes_for_faceting)
|
|
|
|
.service(delete_attributes_for_faceting)
|
|
|
|
.service(update_attributes_for_faceting);
|
2020-04-22 17:43:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[post("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
|
|
|
async fn update_all(
|
2020-04-09 11:11:48 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-04-16 11:09:47 +02:00
|
|
|
body: web::Json<Settings>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-16 11:09:47 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-16 11:09:47 +02:00
|
|
|
|
2020-05-22 18:04:23 +02:00
|
|
|
let update_id = data.db.update_write::<_, _, ResponseError>(|writer| {
|
2020-05-22 12:03:57 +02:00
|
|
|
let settings = body
|
|
|
|
.into_inner()
|
|
|
|
.into_update()
|
|
|
|
.map_err(Error::bad_request)?;
|
2020-05-22 18:04:23 +02:00
|
|
|
let update_id = index.settings_update(writer, settings)?;
|
2020-05-22 12:03:57 +02:00
|
|
|
Ok(update_id)
|
|
|
|
})?;
|
2020-04-16 11:09:47 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
|
|
|
async fn get_all(
|
2020-04-16 11:09:47 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-09 11:11:48 +02:00
|
|
|
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
2020-04-09 11:11:48 +02:00
|
|
|
|
2020-05-22 12:03:57 +02:00
|
|
|
let stop_words: BTreeSet<String> = index
|
|
|
|
.main
|
2020-05-27 12:04:35 +02:00
|
|
|
.stop_words(&reader)?
|
2020-05-22 12:03:57 +02:00
|
|
|
.into_iter()
|
|
|
|
.collect();
|
2020-01-16 19:19:44 +01:00
|
|
|
|
2020-05-27 12:04:35 +02:00
|
|
|
let synonyms_list = index.main.synonyms(&reader)?;
|
2020-01-16 19:19:44 +01:00
|
|
|
|
|
|
|
let mut synonyms = BTreeMap::new();
|
|
|
|
let index_synonyms = &index.synonyms;
|
|
|
|
for synonym in synonyms_list {
|
2020-05-22 18:04:23 +02:00
|
|
|
let list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
|
|
|
|
synonyms.insert(synonym, list);
|
2020-01-16 19:19:44 +01:00
|
|
|
}
|
|
|
|
|
2020-02-26 18:49:17 +01:00
|
|
|
let ranking_rules = index
|
|
|
|
.main
|
2020-04-17 14:52:13 +02:00
|
|
|
.ranking_rules(&reader)?
|
2020-02-26 18:24:19 +01:00
|
|
|
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
|
|
|
.into_iter()
|
|
|
|
.map(|r| r.to_string())
|
|
|
|
.collect();
|
|
|
|
|
2020-04-17 14:52:13 +02:00
|
|
|
let distinct_attribute = index.main.distinct_attribute(&reader)?;
|
2020-01-16 19:19:44 +01:00
|
|
|
|
2020-04-17 14:52:13 +02:00
|
|
|
let schema = index.main.schema(&reader)?;
|
2020-01-16 19:19:44 +01:00
|
|
|
|
2020-05-05 22:27:06 +02:00
|
|
|
let attributes_for_faceting = match (&schema, &index.main.attributes_for_faceting(&reader)?) {
|
|
|
|
(Some(schema), Some(attrs)) => {
|
2020-06-03 10:32:42 +02:00
|
|
|
attrs
|
2020-05-05 22:27:06 +02:00
|
|
|
.iter()
|
2020-06-03 10:24:58 +02:00
|
|
|
.filter_map(|&id| schema.name(id))
|
2020-05-05 22:27:06 +02:00
|
|
|
.map(str::to_string)
|
2020-06-03 10:32:42 +02:00
|
|
|
.collect()
|
2020-05-05 22:27:06 +02:00
|
|
|
}
|
2020-06-03 10:32:42 +02:00
|
|
|
_ => vec![],
|
2020-05-05 22:27:06 +02:00
|
|
|
};
|
|
|
|
|
2020-06-03 10:32:42 +02:00
|
|
|
println!("{:?}", attributes_for_faceting);
|
|
|
|
|
2020-02-12 17:00:14 +01:00
|
|
|
let searchable_attributes = schema.clone().map(|s| {
|
2020-03-10 15:35:19 +01:00
|
|
|
s.indexed_name()
|
2020-02-12 17:00:14 +01:00
|
|
|
.iter()
|
2020-04-24 15:00:52 +02:00
|
|
|
.map(|s| s.to_string())
|
2020-03-10 15:35:19 +01:00
|
|
|
.collect::<Vec<String>>()
|
2020-02-12 17:00:14 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
let displayed_attributes = schema.clone().map(|s| {
|
2020-03-10 15:35:19 +01:00
|
|
|
s.displayed_name()
|
2020-02-12 17:00:14 +01:00
|
|
|
.iter()
|
2020-04-24 15:00:52 +02:00
|
|
|
.map(|s| s.to_string())
|
2020-03-10 15:35:19 +01:00
|
|
|
.collect::<HashSet<String>>()
|
2020-02-12 17:00:14 +01:00
|
|
|
});
|
2020-03-10 15:35:19 +01:00
|
|
|
|
2020-02-25 15:51:37 +01:00
|
|
|
let accept_new_fields = schema.map(|s| s.accept_new_fields());
|
2020-01-16 19:19:44 +01:00
|
|
|
|
|
|
|
let settings = Settings {
|
2020-02-26 18:24:19 +01:00
|
|
|
ranking_rules: Some(Some(ranking_rules)),
|
2020-02-25 16:10:34 +01:00
|
|
|
distinct_attribute: Some(distinct_attribute),
|
2020-03-10 15:35:19 +01:00
|
|
|
searchable_attributes: Some(searchable_attributes),
|
|
|
|
displayed_attributes: Some(displayed_attributes),
|
2020-03-05 14:17:15 +01:00
|
|
|
stop_words: Some(Some(stop_words)),
|
|
|
|
synonyms: Some(Some(synonyms)),
|
2020-02-25 15:51:37 +01:00
|
|
|
accept_new_fields: Some(accept_new_fields),
|
2020-06-03 10:32:42 +02:00
|
|
|
attributes_for_faceting: Some(Some(attributes_for_faceting)),
|
2020-01-16 19:19:44 +01:00
|
|
|
};
|
|
|
|
|
2020-04-09 11:11:48 +02:00
|
|
|
Ok(HttpResponse::Ok().json(settings))
|
2019-10-31 15:00:36 +01:00
|
|
|
}
|
2020-01-27 18:33:40 +01:00
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[delete("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
|
|
|
async fn delete_all(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
ranking_rules: UpdateState::Clear,
|
|
|
|
distinct_attribute: UpdateState::Clear,
|
|
|
|
primary_key: UpdateState::Clear,
|
|
|
|
searchable_attributes: UpdateState::Clear,
|
|
|
|
displayed_attributes: UpdateState::Clear,
|
|
|
|
stop_words: UpdateState::Clear,
|
|
|
|
synonyms: UpdateState::Clear,
|
|
|
|
accept_new_fields: UpdateState::Clear,
|
2020-05-05 22:27:06 +02:00
|
|
|
attributes_for_faceting: UpdateState::Clear,
|
2020-04-10 10:13:08 +02:00
|
|
|
};
|
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/ranking-rules",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_rules(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let ranking_rules = index
|
|
|
|
.main
|
2020-04-17 14:52:13 +02:00
|
|
|
.ranking_rules(&reader)?
|
2020-04-10 10:13:08 +02:00
|
|
|
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
|
|
|
.into_iter()
|
|
|
|
.map(|r| r.to_string())
|
|
|
|
.collect::<Vec<String>>();
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(ranking_rules))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/ranking-rules",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_rules(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<Vec<String>>>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
ranking_rules: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
2020-05-19 18:20:29 +02:00
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[delete(
|
|
|
|
"/indexes/{index_uid}/settings/ranking-rules",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn delete_rules(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
ranking_rules: UpdateState::Clear,
|
|
|
|
..SettingsUpdate::default()
|
|
|
|
};
|
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/distinct-attribute",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_distinct(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
|
|
|
let distinct_attribute = index.main.distinct_attribute(&reader)?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(distinct_attribute))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/distinct-attribute",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_distinct(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<String>>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
distinct_attribute: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
2020-05-19 18:20:29 +02:00
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[delete(
|
|
|
|
"/indexes/{index_uid}/settings/distinct-attribute",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn delete_distinct(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
distinct_attribute: UpdateState::Clear,
|
|
|
|
..SettingsUpdate::default()
|
|
|
|
};
|
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/searchable-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_searchable(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
|
|
|
let schema = index.main.schema(&reader)?;
|
2020-04-10 10:13:08 +02:00
|
|
|
let searchable_attributes: Option<Vec<String>> =
|
2020-04-24 15:00:52 +02:00
|
|
|
schema.map(|s| s.indexed_name().iter().map(|i| i.to_string()).collect());
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(searchable_attributes))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/searchable-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_searchable(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<Vec<String>>>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
searchable_attributes: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
2020-05-19 18:20:29 +02:00
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
2020-05-22 12:03:57 +02:00
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[delete(
|
|
|
|
"/indexes/{index_uid}/settings/searchable-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn delete_searchable(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
searchable_attributes: UpdateState::Clear,
|
|
|
|
..SettingsUpdate::default()
|
|
|
|
};
|
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/displayed-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_displayed(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
2020-04-17 14:52:13 +02:00
|
|
|
let schema = index.main.schema(&reader)?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
2020-04-24 15:00:52 +02:00
|
|
|
let displayed_attributes: Option<HashSet<String>> =
|
|
|
|
schema.map(|s| s.displayed_name().iter().map(|i| i.to_string()).collect());
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(displayed_attributes))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/displayed-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_displayed(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<HashSet<String>>>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
displayed_attributes: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
2020-05-19 18:20:29 +02:00
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[delete(
|
|
|
|
"/indexes/{index_uid}/settings/displayed-attributes",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn delete_displayed(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
displayed_attributes: UpdateState::Clear,
|
|
|
|
..SettingsUpdate::default()
|
|
|
|
};
|
|
|
|
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/accept-new-fields",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_accept_new_fields(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-17 14:52:13 +02:00
|
|
|
let reader = data.db.main_read_txn()?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
2020-04-17 14:52:13 +02:00
|
|
|
let schema = index.main.schema(&reader)?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let accept_new_fields = schema.map(|s| s.accept_new_fields());
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(accept_new_fields))
|
|
|
|
}
|
|
|
|
|
2020-04-22 17:43:51 +02:00
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/accept-new-fields",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_accept_new_fields(
|
2020-04-10 10:13:08 +02:00
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<bool>>,
|
2020-05-22 12:03:57 +02:00
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
2020-04-10 19:05:05 +02:00
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
2020-05-19 18:20:29 +02:00
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
accept_new_fields: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
2020-05-19 18:20:29 +02:00
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
2020-05-28 16:12:24 +02:00
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
2020-04-10 10:13:08 +02:00
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
2020-06-03 10:24:58 +02:00
|
|
|
|
|
|
|
#[get(
|
|
|
|
"/indexes/{index_uid}/settings/attributes-for-faceting",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn get_attributes_for_faceting(
|
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
|
|
|
|
|
|
|
let attributes_for_faceting = data
|
|
|
|
.db
|
2020-06-03 10:32:42 +02:00
|
|
|
.main_read::<_, _, ResponseError>(|reader| {
|
2020-06-03 10:24:58 +02:00
|
|
|
let schema = index.main.schema(reader)?;
|
|
|
|
let attrs = index.main.attributes_for_faceting(reader)?;
|
|
|
|
let attr_names = match (&schema, &attrs) {
|
|
|
|
(Some(schema), Some(attrs)) => {
|
2020-06-03 10:32:42 +02:00
|
|
|
attrs
|
2020-06-03 10:24:58 +02:00
|
|
|
.iter()
|
|
|
|
.filter_map(|&id| schema.name(id))
|
|
|
|
.map(str::to_string)
|
2020-06-03 10:32:42 +02:00
|
|
|
.collect()
|
2020-06-03 10:24:58 +02:00
|
|
|
}
|
2020-06-03 10:32:42 +02:00
|
|
|
_ => vec![]
|
2020-06-03 10:24:58 +02:00
|
|
|
};
|
|
|
|
Ok(attr_names)
|
|
|
|
})?;
|
|
|
|
|
|
|
|
Ok(HttpResponse::Ok().json(attributes_for_faceting))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[post(
|
|
|
|
"/indexes/{index_uid}/settings/attributes-for-faceting",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn update_attributes_for_faceting(
|
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
body: web::Json<Option<Vec<String>>>,
|
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
|
|
|
|
|
|
|
let settings = Settings {
|
|
|
|
attributes_for_faceting: Some(body.into_inner()),
|
|
|
|
..Settings::default()
|
|
|
|
};
|
|
|
|
|
|
|
|
let settings = settings.into_update().map_err(Error::bad_request)?;
|
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|
|
|
|
|
|
|
|
#[delete(
|
|
|
|
"/indexes/{index_uid}/settings/attributes-for-faceting",
|
|
|
|
wrap = "Authentication::Private"
|
|
|
|
)]
|
|
|
|
async fn delete_attributes_for_faceting(
|
|
|
|
data: web::Data<Data>,
|
|
|
|
path: web::Path<IndexParam>,
|
|
|
|
) -> Result<HttpResponse, ResponseError> {
|
|
|
|
let index = data
|
|
|
|
.db
|
|
|
|
.open_index(&path.index_uid)
|
|
|
|
.ok_or(Error::index_not_found(&path.index_uid))?;
|
|
|
|
|
|
|
|
let settings = SettingsUpdate {
|
|
|
|
attributes_for_faceting: UpdateState::Clear,
|
|
|
|
..SettingsUpdate::default()
|
|
|
|
};
|
|
|
|
|
|
|
|
let update_id = data.db.update_write(|w| index.settings_update(w, settings))?;
|
|
|
|
|
|
|
|
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
|
|
|
}
|