mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-07-27 00:31:02 +00:00
prepare boilerplate code for new api
This commit is contained in:
@ -38,23 +38,7 @@ async fn get_document(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<DocumentParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(&path.index_uid)
|
||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||
|
||||
let reader = data.db.main_read_txn()?;
|
||||
|
||||
let internal_id = index
|
||||
.main
|
||||
.external_to_internal_docid(&reader, &path.document_id)?
|
||||
.ok_or(Error::document_not_found(&path.document_id))?;
|
||||
|
||||
let document: Document = index
|
||||
.document(&reader, None, internal_id)?
|
||||
.ok_or(Error::document_not_found(&path.document_id))?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(document))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -65,17 +49,7 @@ async fn delete_document(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<DocumentParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(&path.index_uid)
|
||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||
|
||||
let mut documents_deletion = index.documents_deletion();
|
||||
documents_deletion.delete_document_by_external_docid(path.document_id.clone());
|
||||
|
||||
let update_id = data.db.update_write(|w| documents_deletion.finalize(w))?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -94,32 +68,7 @@ pub fn get_all_documents_sync(
|
||||
limit: usize,
|
||||
attributes_to_retrieve: Option<&String>
|
||||
) -> Result<Vec<Document>, Error> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(index_uid)
|
||||
.ok_or(Error::index_not_found(index_uid))?;
|
||||
|
||||
|
||||
let documents_ids: Result<BTreeSet<_>, _> = index
|
||||
.documents_fields_counts
|
||||
.documents_ids(reader)?
|
||||
.skip(offset)
|
||||
.take(limit)
|
||||
.collect();
|
||||
|
||||
let attributes: Option<HashSet<&str>> = attributes_to_retrieve
|
||||
.map(|a| a.split(',').collect());
|
||||
|
||||
let mut documents = Vec::new();
|
||||
for document_id in documents_ids? {
|
||||
if let Ok(Some(document)) =
|
||||
index.document::<Document>(reader, attributes.as_ref(), document_id)
|
||||
{
|
||||
documents.push(document);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(documents)
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get("/indexes/{index_uid}/documents", wrap = "Authentication::Public")]
|
||||
@ -128,21 +77,7 @@ async fn get_all_documents(
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<BrowseQuery>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let offset = params.offset.unwrap_or(0);
|
||||
let limit = params.limit.unwrap_or(20);
|
||||
let index_uid = &path.index_uid;
|
||||
let reader = data.db.main_read_txn()?;
|
||||
|
||||
let documents = get_all_documents_sync(
|
||||
&data,
|
||||
&reader,
|
||||
index_uid,
|
||||
offset,
|
||||
limit,
|
||||
params.attributes_to_retrieve.as_ref()
|
||||
)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(documents))
|
||||
todo!()
|
||||
}
|
||||
|
||||
fn find_primary_key(document: &IndexMap<String, Value>) -> Option<String> {
|
||||
@ -167,41 +102,7 @@ async fn update_multiple_documents(
|
||||
body: web::Json<Vec<Document>>,
|
||||
is_partial: bool,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let reader = data.db.main_read_txn()?;
|
||||
|
||||
let mut schema = index
|
||||
.main
|
||||
.schema(&reader)?
|
||||
.ok_or(meilisearch_core::Error::SchemaMissing)?;
|
||||
|
||||
if schema.primary_key().is_none() {
|
||||
let id = match ¶ms.primary_key {
|
||||
Some(id) => id.to_string(),
|
||||
None => body
|
||||
.first()
|
||||
.and_then(find_primary_key)
|
||||
.ok_or(meilisearch_core::Error::MissingPrimaryKey)?,
|
||||
};
|
||||
|
||||
schema.set_primary_key(&id).map_err(Error::bad_request)?;
|
||||
|
||||
data.db.main_write(|w| index.main.put_schema(w, &schema))?;
|
||||
}
|
||||
|
||||
let mut document_addition = if is_partial {
|
||||
index.documents_partial_addition()
|
||||
} else {
|
||||
index.documents_addition()
|
||||
};
|
||||
|
||||
for document in body.into_inner() {
|
||||
document_addition.update_document(document);
|
||||
}
|
||||
|
||||
Ok(data.db.update_write(|w| document_addition.finalize(w))?)
|
||||
})?;
|
||||
return Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)));
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]
|
||||
@ -211,7 +112,7 @@ async fn add_documents(
|
||||
params: web::Query<UpdateDocumentsQuery>,
|
||||
body: web::Json<Vec<Document>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
update_multiple_documents(data, path, params, body, false).await
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[put("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]
|
||||
@ -233,21 +134,7 @@ async fn delete_documents(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Vec<Value>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(&path.index_uid)
|
||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||
|
||||
let mut documents_deletion = index.documents_deletion();
|
||||
|
||||
for document_id in body.into_inner() {
|
||||
let document_id = update::value_to_string(&document_id);
|
||||
documents_deletion.delete_document_by_external_docid(document_id);
|
||||
}
|
||||
|
||||
let update_id = data.db.update_write(|w| documents_deletion.finalize(w))?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]
|
||||
@ -255,12 +142,5 @@ async fn clear_all_documents(
|
||||
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 update_id = data.db.update_write(|w| index.clear_all(w))?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
@ -19,11 +19,7 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
async fn trigger_dump(
|
||||
data: web::Data<Data>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let dumps_dir = Path::new(&data.dumps_dir);
|
||||
match init_dump_process(&data, &dumps_dir) {
|
||||
Ok(resume) => Ok(HttpResponse::Accepted().json(resume)),
|
||||
Err(e) => Err(e.into())
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@ -42,23 +38,5 @@ async fn get_dump_status(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<DumpParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let dumps_dir = Path::new(&data.dumps_dir);
|
||||
let dump_uid = &path.dump_uid;
|
||||
|
||||
if let Some(resume) = DumpInfo::get_current() {
|
||||
if &resume.uid == dump_uid {
|
||||
return Ok(HttpResponse::Ok().json(resume));
|
||||
}
|
||||
}
|
||||
|
||||
if File::open(compressed_dumps_dir(Path::new(dumps_dir), dump_uid)).is_ok() {
|
||||
let resume = DumpInfo::new(
|
||||
dump_uid.into(),
|
||||
DumpStatus::Done
|
||||
);
|
||||
|
||||
Ok(HttpResponse::Ok().json(resume))
|
||||
} else {
|
||||
Err(Error::not_found("dump does not exist").into())
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
@ -23,12 +23,7 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
}
|
||||
|
||||
fn generate_uid() -> String {
|
||||
let mut rng = rand::thread_rng();
|
||||
let sample = b"abcdefghijklmnopqrstuvwxyz0123456789";
|
||||
sample
|
||||
.choose_multiple(&mut rng, 8)
|
||||
.map(|c| *c as char)
|
||||
.collect()
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||
@ -42,54 +37,7 @@ pub struct IndexResponse {
|
||||
}
|
||||
|
||||
pub fn list_indexes_sync(data: &web::Data<Data>, reader: &MainReader) -> Result<Vec<IndexResponse>, ResponseError> {
|
||||
let mut indexes = Vec::new();
|
||||
|
||||
for index_uid in data.db.indexes_uids() {
|
||||
let index = data.db.open_index(&index_uid);
|
||||
|
||||
match index {
|
||||
Some(index) => {
|
||||
let name = index.main.name(reader)?.ok_or(Error::internal(
|
||||
"Impossible to get the name of an index",
|
||||
))?;
|
||||
let created_at = index
|
||||
.main
|
||||
.created_at(reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the create date of an index",
|
||||
))?;
|
||||
let updated_at = index
|
||||
.main
|
||||
.updated_at(reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the last update date of an index",
|
||||
))?;
|
||||
|
||||
let primary_key = match index.main.schema(reader) {
|
||||
Ok(Some(schema)) => match schema.primary_key() {
|
||||
Some(primary_key) => Some(primary_key.to_owned()),
|
||||
None => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let index_response = IndexResponse {
|
||||
name,
|
||||
uid: index_uid,
|
||||
created_at,
|
||||
updated_at,
|
||||
primary_key,
|
||||
};
|
||||
indexes.push(index_response);
|
||||
}
|
||||
None => error!(
|
||||
"Index {} is referenced in the indexes list but cannot be found",
|
||||
index_uid
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
Ok(indexes)
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get("/indexes", wrap = "Authentication::Private")]
|
||||
@ -105,44 +53,7 @@ async fn get_index(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
let name = index.main.name(&reader)?.ok_or(Error::internal(
|
||||
"Impossible to get the name of an index",
|
||||
))?;
|
||||
let created_at = index
|
||||
.main
|
||||
.created_at(&reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the create date of an index",
|
||||
))?;
|
||||
let updated_at = index
|
||||
.main
|
||||
.updated_at(&reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the last update date of an index",
|
||||
))?;
|
||||
|
||||
let primary_key = match index.main.schema(&reader) {
|
||||
Ok(Some(schema)) => match schema.primary_key() {
|
||||
Some(primary_key) => Some(primary_key.to_owned()),
|
||||
None => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
let index_response = IndexResponse {
|
||||
name,
|
||||
uid: path.index_uid.clone(),
|
||||
created_at,
|
||||
updated_at,
|
||||
primary_key,
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(index_response))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -160,46 +71,7 @@ pub fn create_index_sync(
|
||||
name: String,
|
||||
primary_key: Option<String>,
|
||||
) -> Result<IndexResponse, Error> {
|
||||
|
||||
let created_index = database
|
||||
.create_index(&uid)
|
||||
.map_err(|e| match e {
|
||||
meilisearch_core::Error::IndexAlreadyExists => Error::IndexAlreadyExists(uid.clone()),
|
||||
_ => Error::create_index(e)
|
||||
})?;
|
||||
|
||||
let index_response = database.main_write::<_, _, Error>(|mut write_txn| {
|
||||
created_index.main.put_name(&mut write_txn, &name)?;
|
||||
|
||||
let created_at = created_index
|
||||
.main
|
||||
.created_at(&write_txn)?
|
||||
.ok_or(Error::internal("Impossible to read created at"))?;
|
||||
|
||||
let updated_at = created_index
|
||||
.main
|
||||
.updated_at(&write_txn)?
|
||||
.ok_or(Error::internal("Impossible to read updated at"))?;
|
||||
|
||||
if let Some(id) = primary_key.clone() {
|
||||
if let Some(mut schema) = created_index.main.schema(&write_txn)? {
|
||||
schema
|
||||
.set_primary_key(&id)
|
||||
.map_err(Error::bad_request)?;
|
||||
created_index.main.put_schema(&mut write_txn, &schema)?;
|
||||
}
|
||||
}
|
||||
let index_response = IndexResponse {
|
||||
name,
|
||||
uid,
|
||||
created_at,
|
||||
updated_at,
|
||||
primary_key,
|
||||
};
|
||||
Ok(index_response)
|
||||
})?;
|
||||
|
||||
Ok(index_response)
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post("/indexes", wrap = "Authentication::Private")]
|
||||
@ -207,36 +79,7 @@ async fn create_index(
|
||||
data: web::Data<Data>,
|
||||
body: web::Json<IndexCreateRequest>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
if let (None, None) = (body.name.clone(), body.uid.clone()) {
|
||||
return Err(Error::bad_request(
|
||||
"Index creation must have an uid",
|
||||
).into());
|
||||
}
|
||||
|
||||
let uid = match &body.uid {
|
||||
Some(uid) => {
|
||||
if uid
|
||||
.chars()
|
||||
.all(|x| x.is_ascii_alphanumeric() || x == '-' || x == '_')
|
||||
{
|
||||
uid.to_owned()
|
||||
} else {
|
||||
return Err(Error::InvalidIndexUid.into());
|
||||
}
|
||||
}
|
||||
None => loop {
|
||||
let uid = generate_uid();
|
||||
if data.db.open_index(&uid).is_none() {
|
||||
break uid;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
let name = body.name.as_ref().unwrap_or(&uid).to_string();
|
||||
|
||||
let index_response = create_index_sync(&data.db, uid, name, body.primary_key.clone())?;
|
||||
|
||||
Ok(HttpResponse::Created().json(index_response))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
@ -262,60 +105,7 @@ async fn update_index(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<IndexCreateRequest>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(&path.index_uid)
|
||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||
|
||||
data.db.main_write::<_, _, ResponseError>(|writer| {
|
||||
if let Some(name) = &body.name {
|
||||
index.main.put_name(writer, name)?;
|
||||
}
|
||||
|
||||
if let Some(id) = body.primary_key.clone() {
|
||||
if let Some(mut schema) = index.main.schema(writer)? {
|
||||
schema.set_primary_key(&id)?;
|
||||
index.main.put_schema(writer, &schema)?;
|
||||
}
|
||||
}
|
||||
index.main.put_updated_at(writer)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let reader = data.db.main_read_txn()?;
|
||||
let name = index.main.name(&reader)?.ok_or(Error::internal(
|
||||
"Impossible to get the name of an index",
|
||||
))?;
|
||||
let created_at = index
|
||||
.main
|
||||
.created_at(&reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the create date of an index",
|
||||
))?;
|
||||
let updated_at = index
|
||||
.main
|
||||
.updated_at(&reader)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to get the last update date of an index",
|
||||
))?;
|
||||
|
||||
let primary_key = match index.main.schema(&reader) {
|
||||
Ok(Some(schema)) => match schema.primary_key() {
|
||||
Some(primary_key) => Some(primary_key.to_owned()),
|
||||
None => None,
|
||||
},
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let index_response = IndexResponse {
|
||||
name,
|
||||
uid: path.index_uid.clone(),
|
||||
created_at,
|
||||
updated_at,
|
||||
primary_key,
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(index_response))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete("/indexes/{index_uid}", wrap = "Authentication::Private")]
|
||||
@ -323,11 +113,7 @@ async fn delete_index(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<IndexParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
if data.db.delete_index(&path.index_uid)? {
|
||||
Ok(HttpResponse::NoContent().finish())
|
||||
} else {
|
||||
Err(Error::index_not_found(&path.index_uid).into())
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -344,34 +130,14 @@ async fn get_update_status(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<UpdateParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(&path.index_uid)
|
||||
.ok_or(Error::index_not_found(&path.index_uid))?;
|
||||
|
||||
let reader = data.db.update_read_txn()?;
|
||||
|
||||
let status = index.update_status(&reader, path.update_id)?;
|
||||
|
||||
match status {
|
||||
Some(status) => Ok(HttpResponse::Ok().json(status)),
|
||||
None => Err(Error::NotFound(format!(
|
||||
"Update {}",
|
||||
path.update_id
|
||||
)).into()),
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
pub fn get_all_updates_status_sync(
|
||||
data: &web::Data<Data>,
|
||||
reader: &UpdateReader,
|
||||
index_uid: &str,
|
||||
) -> Result<Vec<UpdateStatus>, Error> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(index_uid)
|
||||
.ok_or(Error::index_not_found(index_uid))?;
|
||||
|
||||
Ok(index.all_updates_status(reader)?)
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get("/indexes/{index_uid}/updates", wrap = "Authentication::Private")]
|
||||
@ -379,10 +145,5 @@ async fn get_all_updates_status(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<IndexParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
|
||||
let reader = data.db.update_read_txn()?;
|
||||
|
||||
let response = get_all_updates_status_sync(&data, &reader, &path.index_uid)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(response))
|
||||
todo!()
|
||||
}
|
||||
|
@ -18,9 +18,5 @@ struct KeysResponse {
|
||||
|
||||
#[get("/keys", wrap = "Authentication::Admin")]
|
||||
async fn list(data: web::Data<Data>) -> HttpResponse {
|
||||
let api_keys = data.api_keys.clone();
|
||||
HttpResponse::Ok().json(KeysResponse {
|
||||
private: api_keys.private,
|
||||
public: api_keys.public,
|
||||
})
|
||||
todo!()
|
||||
}
|
||||
|
@ -40,8 +40,7 @@ async fn search_with_url_query(
|
||||
path: web::Path<IndexParam>,
|
||||
params: web::Query<SearchQuery>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let search_result = params.search(&path.index_uid, data)?;
|
||||
Ok(HttpResponse::Ok().json(search_result))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -95,175 +94,5 @@ impl SearchQuery {
|
||||
index_uid: &str,
|
||||
data: web::Data<Data>,
|
||||
) -> Result<SearchResult, ResponseError> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(index_uid)
|
||||
.ok_or(Error::index_not_found(index_uid))?;
|
||||
|
||||
let reader = data.db.main_read_txn()?;
|
||||
let schema = index
|
||||
.main
|
||||
.schema(&reader)?
|
||||
.ok_or(Error::internal("Impossible to retrieve the schema"))?;
|
||||
|
||||
let query = self
|
||||
.q
|
||||
.clone()
|
||||
.and_then(|q| if q.is_empty() { None } else { Some(q) });
|
||||
|
||||
let mut search_builder = index.new_search(query);
|
||||
|
||||
if let Some(offset) = self.offset {
|
||||
search_builder.offset(offset);
|
||||
}
|
||||
if let Some(limit) = self.limit {
|
||||
search_builder.limit(limit);
|
||||
}
|
||||
|
||||
let available_attributes = schema.displayed_name();
|
||||
let mut restricted_attributes: HashSet<&str>;
|
||||
match &self.attributes_to_retrieve {
|
||||
Some(attributes_to_retrieve) => {
|
||||
let attributes_to_retrieve: HashSet<&str> =
|
||||
attributes_to_retrieve.split(',').collect();
|
||||
if attributes_to_retrieve.contains("*") {
|
||||
restricted_attributes = available_attributes.clone();
|
||||
} else {
|
||||
restricted_attributes = HashSet::new();
|
||||
for attr in attributes_to_retrieve {
|
||||
if available_attributes.contains(attr) {
|
||||
restricted_attributes.insert(attr);
|
||||
search_builder.add_retrievable_field(attr.to_string());
|
||||
} else {
|
||||
warn!("The attributes {:?} present in attributesToCrop parameter doesn't exist", attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => {
|
||||
restricted_attributes = available_attributes.clone();
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref facet_filters) = self.facet_filters {
|
||||
let attrs = index
|
||||
.main
|
||||
.attributes_for_faceting(&reader)?
|
||||
.unwrap_or_default();
|
||||
search_builder.add_facet_filters(FacetFilter::from_str(
|
||||
facet_filters,
|
||||
&schema,
|
||||
&attrs,
|
||||
)?);
|
||||
}
|
||||
|
||||
if let Some(facets) = &self.facets_distribution {
|
||||
match index.main.attributes_for_faceting(&reader)? {
|
||||
Some(ref attrs) => {
|
||||
let field_ids = prepare_facet_list(&facets, &schema, attrs)?;
|
||||
search_builder.add_facets(field_ids);
|
||||
}
|
||||
None => return Err(FacetCountError::NoFacetSet.into()),
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(attributes_to_crop) = &self.attributes_to_crop {
|
||||
let default_length = self.crop_length.unwrap_or(200);
|
||||
let mut final_attributes: HashMap<String, usize> = HashMap::new();
|
||||
|
||||
for attribute in attributes_to_crop.split(',') {
|
||||
let mut attribute = attribute.split(':');
|
||||
let attr = attribute.next();
|
||||
let length = attribute
|
||||
.next()
|
||||
.and_then(|s| s.parse().ok())
|
||||
.unwrap_or(default_length);
|
||||
match attr {
|
||||
Some("*") => {
|
||||
for attr in &restricted_attributes {
|
||||
final_attributes.insert(attr.to_string(), length);
|
||||
}
|
||||
}
|
||||
Some(attr) => {
|
||||
if available_attributes.contains(attr) {
|
||||
final_attributes.insert(attr.to_string(), length);
|
||||
} else {
|
||||
warn!("The attributes {:?} present in attributesToCrop parameter doesn't exist", attr);
|
||||
}
|
||||
}
|
||||
None => (),
|
||||
}
|
||||
}
|
||||
search_builder.attributes_to_crop(final_attributes);
|
||||
}
|
||||
|
||||
if let Some(attributes_to_highlight) = &self.attributes_to_highlight {
|
||||
let mut final_attributes: HashSet<String> = HashSet::new();
|
||||
for attribute in attributes_to_highlight.split(',') {
|
||||
if attribute == "*" {
|
||||
for attr in &restricted_attributes {
|
||||
final_attributes.insert(attr.to_string());
|
||||
}
|
||||
} else if available_attributes.contains(attribute) {
|
||||
final_attributes.insert(attribute.to_string());
|
||||
} else {
|
||||
warn!("The attributes {:?} present in attributesToHighlight parameter doesn't exist", attribute);
|
||||
}
|
||||
}
|
||||
|
||||
search_builder.attributes_to_highlight(final_attributes);
|
||||
}
|
||||
|
||||
if let Some(filters) = &self.filters {
|
||||
search_builder.filters(filters.to_string());
|
||||
}
|
||||
|
||||
if let Some(matches) = self.matches {
|
||||
if matches {
|
||||
search_builder.get_matches();
|
||||
}
|
||||
}
|
||||
search_builder.search(&reader)
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the incoming string into an array of attributes for which to return a count. It returns
|
||||
/// a Vec of attribute names ascociated with their id.
|
||||
///
|
||||
/// An error is returned if the array is malformed, or if it contains attributes that are
|
||||
/// unexisting, or not set as facets.
|
||||
fn prepare_facet_list(
|
||||
facets: &str,
|
||||
schema: &Schema,
|
||||
facet_attrs: &[FieldId],
|
||||
) -> Result<Vec<(FieldId, String)>, FacetCountError> {
|
||||
let json_array = serde_json::from_str(facets)?;
|
||||
match json_array {
|
||||
Value::Array(vals) => {
|
||||
let wildcard = Value::String("*".to_string());
|
||||
if vals.iter().any(|f| f == &wildcard) {
|
||||
let attrs = facet_attrs
|
||||
.iter()
|
||||
.filter_map(|&id| schema.name(id).map(|n| (id, n.to_string())))
|
||||
.collect();
|
||||
return Ok(attrs);
|
||||
}
|
||||
let mut field_ids = Vec::with_capacity(facet_attrs.len());
|
||||
for facet in vals {
|
||||
match facet {
|
||||
Value::String(facet) => {
|
||||
if let Some(id) = schema.id(&facet) {
|
||||
if !facet_attrs.contains(&id) {
|
||||
return Err(FacetCountError::AttributeNotSet(facet));
|
||||
}
|
||||
field_ids.push((id, facet));
|
||||
}
|
||||
}
|
||||
bad_val => return Err(FacetCountError::unexpected_token(bad_val, &["String"])),
|
||||
}
|
||||
}
|
||||
Ok(field_ids)
|
||||
}
|
||||
bad_val => Err(FacetCountError::unexpected_token(bad_val, &["[String]"])),
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
@ -32,91 +32,13 @@ pub fn services(cfg: &mut web::ServiceConfig) {
|
||||
.service(update_attributes_for_faceting);
|
||||
}
|
||||
|
||||
pub fn update_all_settings_txn(
|
||||
data: &web::Data<Data>,
|
||||
settings: SettingsUpdate,
|
||||
index_uid: &str,
|
||||
write_txn: &mut UpdateWriter,
|
||||
) -> Result<u64, Error> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(index_uid)
|
||||
.ok_or(Error::index_not_found(index_uid))?;
|
||||
|
||||
let update_id = index.settings_update(write_txn, settings)?;
|
||||
Ok(update_id)
|
||||
}
|
||||
|
||||
#[post("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
||||
async fn update_all(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Settings>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
Ok(data.db.update_write::<_, _, ResponseError>(|writer| {
|
||||
let settings = body.into_inner().to_update().map_err(Error::bad_request)?;
|
||||
let update_id = index.settings_update(writer, settings)?;
|
||||
Ok(update_id)
|
||||
})?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
}
|
||||
|
||||
pub fn get_all_sync(data: &web::Data<Data>, reader: &MainReader, index_uid: &str) -> Result<Settings, Error> {
|
||||
let index = data
|
||||
.db
|
||||
.open_index(index_uid)
|
||||
.ok_or(Error::index_not_found(index_uid))?;
|
||||
|
||||
let stop_words: BTreeSet<String> = index.main.stop_words(&reader)?.into_iter().collect();
|
||||
|
||||
let synonyms_list = index.main.synonyms(reader)?;
|
||||
|
||||
let mut synonyms = BTreeMap::new();
|
||||
let index_synonyms = &index.synonyms;
|
||||
for synonym in synonyms_list {
|
||||
let list = index_synonyms.synonyms(reader, synonym.as_bytes())?;
|
||||
synonyms.insert(synonym, list);
|
||||
}
|
||||
|
||||
let ranking_rules = index
|
||||
.main
|
||||
.ranking_rules(reader)?
|
||||
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
||||
.into_iter()
|
||||
.map(|r| r.to_string())
|
||||
.collect();
|
||||
|
||||
let schema = index.main.schema(&reader)?;
|
||||
|
||||
let distinct_attribute = match (index.main.distinct_attribute(reader)?, &schema) {
|
||||
(Some(id), Some(schema)) => schema.name(id).map(str::to_string),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
let attributes_for_faceting = match (&schema, &index.main.attributes_for_faceting(&reader)?) {
|
||||
(Some(schema), Some(attrs)) => attrs
|
||||
.iter()
|
||||
.filter_map(|&id| schema.name(id))
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
_ => vec![],
|
||||
};
|
||||
|
||||
let searchable_attributes = schema.as_ref().map(get_indexed_attributes);
|
||||
let displayed_attributes = schema.as_ref().map(get_displayed_attributes);
|
||||
|
||||
Ok(Settings {
|
||||
ranking_rules: Some(Some(ranking_rules)),
|
||||
distinct_attribute: Some(distinct_attribute),
|
||||
searchable_attributes: Some(searchable_attributes),
|
||||
displayed_attributes: Some(displayed_attributes),
|
||||
stop_words: Some(Some(stop_words)),
|
||||
synonyms: Some(Some(synonyms)),
|
||||
attributes_for_faceting: Some(Some(attributes_for_faceting)),
|
||||
})
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
||||
@ -124,10 +46,7 @@ async fn get_all(
|
||||
data: web::Data<Data>,
|
||||
path: web::Path<IndexParam>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let reader = data.db.main_read_txn()?;
|
||||
let settings = get_all_sync(&data, &reader, &path.index_uid)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(settings))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete("/indexes/{index_uid}/settings", wrap = "Authentication::Private")]
|
||||
@ -135,27 +54,7 @@ async fn delete_all(
|
||||
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 {
|
||||
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,
|
||||
attributes_for_faceting: UpdateState::Clear,
|
||||
};
|
||||
|
||||
let update_id = data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get(
|
||||
@ -166,21 +65,7 @@ async fn get_rules(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
|
||||
let ranking_rules = index
|
||||
.main
|
||||
.ranking_rules(&reader)?
|
||||
.unwrap_or(DEFAULT_RANKING_RULES.to_vec())
|
||||
.into_iter()
|
||||
.map(|r| r.to_string())
|
||||
.collect::<Vec<String>>();
|
||||
|
||||
Ok(HttpResponse::Ok().json(ranking_rules))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -192,19 +77,7 @@ async fn update_rules(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Option<Vec<String>>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = Settings {
|
||||
ranking_rules: Some(body.into_inner()),
|
||||
..Settings::default()
|
||||
};
|
||||
|
||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -215,21 +88,7 @@ async fn delete_rules(
|
||||
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 {
|
||||
ranking_rules: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get(
|
||||
@ -240,19 +99,7 @@ async fn get_distinct(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
let distinct_attribute_id = index.main.distinct_attribute(&reader)?;
|
||||
let schema = index.main.schema(&reader)?;
|
||||
let distinct_attribute = match (schema, distinct_attribute_id) {
|
||||
(Some(schema), Some(id)) => schema.name(id).map(str::to_string),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(distinct_attribute))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -264,19 +111,7 @@ async fn update_distinct(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Option<String>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = Settings {
|
||||
distinct_attribute: Some(body.into_inner()),
|
||||
..Settings::default()
|
||||
};
|
||||
|
||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -287,21 +122,7 @@ async fn delete_distinct(
|
||||
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 {
|
||||
distinct_attribute: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get(
|
||||
@ -312,15 +133,7 @@ async fn get_searchable(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
let schema = index.main.schema(&reader)?;
|
||||
let searchable_attributes: Option<Vec<String>> = schema.as_ref().map(get_indexed_attributes);
|
||||
|
||||
Ok(HttpResponse::Ok().json(searchable_attributes))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -332,20 +145,7 @@ async fn update_searchable(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Option<Vec<String>>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = Settings {
|
||||
searchable_attributes: Some(body.into_inner()),
|
||||
..Settings::default()
|
||||
};
|
||||
|
||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -356,21 +156,7 @@ async fn delete_searchable(
|
||||
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 {
|
||||
searchable_attributes: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get(
|
||||
@ -381,17 +167,7 @@ async fn get_displayed(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
|
||||
let schema = index.main.schema(&reader)?;
|
||||
|
||||
let displayed_attributes = schema.as_ref().map(get_displayed_attributes);
|
||||
|
||||
Ok(HttpResponse::Ok().json(displayed_attributes))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -403,19 +179,7 @@ async fn update_displayed(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Option<BTreeSet<String>>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = Settings {
|
||||
displayed_attributes: Some(body.into_inner()),
|
||||
..Settings::default()
|
||||
};
|
||||
|
||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -426,21 +190,7 @@ async fn delete_displayed(
|
||||
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 {
|
||||
displayed_attributes: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[get(
|
||||
@ -451,26 +201,7 @@ 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.main_read::<_, _, ResponseError>(|reader| {
|
||||
let schema = index.main.schema(reader)?;
|
||||
let attrs = index.main.attributes_for_faceting(reader)?;
|
||||
let attr_names = match (&schema, &attrs) {
|
||||
(Some(schema), Some(attrs)) => attrs
|
||||
.iter()
|
||||
.filter_map(|&id| schema.name(id))
|
||||
.map(str::to_string)
|
||||
.collect(),
|
||||
_ => vec![],
|
||||
};
|
||||
Ok(attr_names)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(attributes_for_faceting))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -482,19 +213,7 @@ async fn update_attributes_for_faceting(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<Option<Vec<String>>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = Settings {
|
||||
attributes_for_faceting: Some(body.into_inner()),
|
||||
..Settings::default()
|
||||
};
|
||||
|
||||
let settings = settings.to_update().map_err(Error::bad_request)?;
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -505,43 +224,5 @@ 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)))
|
||||
}
|
||||
|
||||
fn get_indexed_attributes(schema: &Schema) -> Vec<String> {
|
||||
if schema.is_indexed_all() {
|
||||
["*"].iter().map(|s| s.to_string()).collect()
|
||||
} else {
|
||||
schema
|
||||
.indexed_name()
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_displayed_attributes(schema: &Schema) -> BTreeSet<String> {
|
||||
if schema.is_displayed_all() {
|
||||
["*"].iter().map(|s| s.to_string()).collect()
|
||||
} else {
|
||||
schema
|
||||
.displayed_name()
|
||||
.iter()
|
||||
.map(|s| s.to_string())
|
||||
.collect()
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
|
@ -32,30 +32,7 @@ async fn index_stats(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
|
||||
let number_of_documents = index.main.number_of_documents(&reader)?;
|
||||
|
||||
let fields_distribution = index.main.fields_distribution(&reader)?.unwrap_or_default();
|
||||
|
||||
let update_reader = data.db.update_read_txn()?;
|
||||
|
||||
let is_indexing =
|
||||
data.db.is_indexing(&update_reader, &path.index_uid)?
|
||||
.ok_or(Error::internal(
|
||||
"Impossible to know if the database is indexing",
|
||||
))?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(IndexStatsResponse {
|
||||
number_of_documents,
|
||||
is_indexing,
|
||||
fields_distribution,
|
||||
}))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@ -68,52 +45,7 @@ struct StatsResult {
|
||||
|
||||
#[get("/stats", wrap = "Authentication::Private")]
|
||||
async fn get_stats(data: web::Data<Data>) -> Result<HttpResponse, ResponseError> {
|
||||
let mut index_list = HashMap::new();
|
||||
|
||||
let reader = data.db.main_read_txn()?;
|
||||
let update_reader = data.db.update_read_txn()?;
|
||||
|
||||
let indexes_set = data.db.indexes_uids();
|
||||
for index_uid in indexes_set {
|
||||
let index = data.db.open_index(&index_uid);
|
||||
match index {
|
||||
Some(index) => {
|
||||
let number_of_documents = index.main.number_of_documents(&reader)?;
|
||||
|
||||
let fields_distribution = index.main.fields_distribution(&reader)?.unwrap_or_default();
|
||||
|
||||
let is_indexing = data.db.is_indexing(&update_reader, &index_uid)?.ok_or(
|
||||
Error::internal("Impossible to know if the database is indexing"),
|
||||
)?;
|
||||
|
||||
let response = IndexStatsResponse {
|
||||
number_of_documents,
|
||||
is_indexing,
|
||||
fields_distribution,
|
||||
};
|
||||
index_list.insert(index_uid, response);
|
||||
}
|
||||
None => error!(
|
||||
"Index {:?} is referenced in the indexes list but cannot be found",
|
||||
index_uid
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
let database_size = WalkDir::new(&data.db_path)
|
||||
.into_iter()
|
||||
.filter_map(|entry| entry.ok())
|
||||
.filter_map(|entry| entry.metadata().ok())
|
||||
.filter(|metadata| metadata.is_file())
|
||||
.fold(0, |acc, m| acc + m.len());
|
||||
|
||||
let last_update = data.db.last_update(&reader)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(StatsResult {
|
||||
database_size,
|
||||
last_update,
|
||||
indexes: index_list,
|
||||
}))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
@ -126,9 +58,5 @@ struct VersionResponse {
|
||||
|
||||
#[get("/version", wrap = "Authentication::Private")]
|
||||
async fn get_version() -> HttpResponse {
|
||||
HttpResponse::Ok().json(VersionResponse {
|
||||
commit_sha: env!("VERGEN_SHA").to_string(),
|
||||
build_date: env!("VERGEN_BUILD_TIMESTAMP").to_string(),
|
||||
pkg_version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
})
|
||||
todo!()
|
||||
}
|
||||
|
@ -20,14 +20,7 @@ async fn get(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
let stop_words = index.main.stop_words(&reader)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(stop_words))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -39,18 +32,7 @@ async fn update(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<BTreeSet<String>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = SettingsUpdate {
|
||||
stop_words: UpdateState::Update(body.into_inner()),
|
||||
..SettingsUpdate::default()
|
||||
};
|
||||
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -61,19 +43,5 @@ async fn delete(
|
||||
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 {
|
||||
stop_words: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
@ -22,23 +22,7 @@ async fn get(
|
||||
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 reader = data.db.main_read_txn()?;
|
||||
|
||||
let synonyms_list = index.main.synonyms(&reader)?;
|
||||
|
||||
let mut synonyms = IndexMap::new();
|
||||
let index_synonyms = &index.synonyms;
|
||||
for synonym in synonyms_list {
|
||||
let list = index_synonyms.synonyms(&reader, synonym.as_bytes())?;
|
||||
synonyms.insert(synonym, list);
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(synonyms))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[post(
|
||||
@ -50,18 +34,7 @@ async fn update(
|
||||
path: web::Path<IndexParam>,
|
||||
body: web::Json<BTreeMap<String, Vec<String>>>,
|
||||
) -> Result<HttpResponse, ResponseError> {
|
||||
let update_id = data.get_or_create_index(&path.index_uid, |index| {
|
||||
let settings = SettingsUpdate {
|
||||
synonyms: UpdateState::Update(body.into_inner()),
|
||||
..SettingsUpdate::default()
|
||||
};
|
||||
|
||||
Ok(data
|
||||
.db
|
||||
.update_write(|w| index.settings_update(w, settings))?)
|
||||
})?;
|
||||
|
||||
Ok(HttpResponse::Accepted().json(IndexUpdateResponse::with_id(update_id)))
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[delete(
|
||||
@ -72,19 +45,5 @@ async fn delete(
|
||||
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 {
|
||||
synonyms: 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)))
|
||||
todo!()
|
||||
}
|
||||
|
Reference in New Issue
Block a user