implement delete document batches

This commit is contained in:
mpostma 2021-02-12 17:39:14 +01:00
parent a8ba809656
commit c317af58bc
No known key found for this signature in database
GPG Key ID: CBC8A7C1D7A28C3A
5 changed files with 68 additions and 7 deletions

View File

@ -72,6 +72,17 @@ impl Data {
Ok(update.into())
}
pub async fn delete_documents(
&self,
index: impl AsRef<str>,
document_ids: Vec<String>,
) -> anyhow::Result<UpdateStatus> {
let index_controller = self.index_controller.clone();
let index = index.as_ref().to_string();
let update = tokio::task::spawn_blocking(move || index_controller.delete_documents(index, document_ids)).await??;
Ok(update.into())
}
#[inline]
pub fn get_update_status(&self, index: impl AsRef<str>, uid: u64) -> anyhow::Result<Option<UpdateStatus>> {
self.index_controller.update_status(index, uid)

View File

@ -43,7 +43,7 @@ impl IndexController for LocalIndexController {
) -> anyhow::Result<UpdateStatus<UpdateMeta, UpdateResult, String>> {
let (_, update_store) = self.indexes.get_or_create_index(&index, self.update_db_size, self.index_db_size)?;
let meta = UpdateMeta::DocumentsAddition { method, format };
let pending = update_store.register_update(meta, data).unwrap();
let pending = update_store.register_update(meta, data)?;
Ok(pending.into())
}
@ -54,7 +54,7 @@ impl IndexController for LocalIndexController {
) -> anyhow::Result<UpdateStatus<UpdateMeta, UpdateResult, String>> {
let (_, update_store) = self.indexes.get_or_create_index(&index, self.update_db_size, self.index_db_size)?;
let meta = UpdateMeta::Settings(settings);
let pending = update_store.register_update(meta, &[]).unwrap();
let pending = update_store.register_update(meta, &[])?;
Ok(pending.into())
}
@ -187,7 +187,16 @@ impl IndexController for LocalIndexController {
let (_, update_store) = self.indexes.index(&index)?
.with_context(|| format!("Index {:?} doesn't exist", index.as_ref()))?;
let meta = UpdateMeta::ClearDocuments;
let pending = update_store.register_update(meta, &[]).unwrap();
let pending = update_store.register_update(meta, &[])?;
Ok(pending.into())
}
fn delete_documents(&self, index: impl AsRef<str>, document_ids: Vec<String>) -> anyhow::Result<super::UpdateStatus> {
let (_, update_store) = self.indexes.index(&index)?
.with_context(|| format!("Index {:?} doesn't exist", index.as_ref()))?;
let meta = UpdateMeta::DeleteDocuments;
let content = serde_json::to_vec(&document_ids)?;
let pending = update_store.register_update(meta, &content)?;
Ok(pending.into())
}
}

View File

@ -177,6 +177,27 @@ impl UpdateHandler {
Err(e) => Err(e.into())
}
}
fn delete_documents(
&self,
document_ids: &[u8],
update_builder: UpdateBuilder,
) -> anyhow::Result<UpdateResult> {
let ids: Vec<String> = serde_json::from_slice(document_ids)?;
let mut txn = self.index.write_txn()?;
let mut builder = update_builder.delete_documents(&mut txn, &self.index)?;
// we ignore unexisting document ids
ids.iter().for_each(|id| { builder.delete_external_id(id); });
match builder.execute() {
Ok(deleted) => txn
.commit()
.and(Ok(UpdateResult::DocumentDeletion { deleted }))
.map_err(Into::into),
Err(e) => Err(e.into())
}
}
}
impl HandleUpdate<UpdateMeta, UpdateResult, String> for UpdateHandler {
@ -194,6 +215,7 @@ impl HandleUpdate<UpdateMeta, UpdateResult, String> for UpdateHandler {
let result = match meta.meta() {
DocumentsAddition { method, format } => self.update_documents(*format, *method, content, update_builder),
ClearDocuments => self.clear_documents(update_builder),
DeleteDocuments => self.delete_documents(content, update_builder,),
Settings(settings) => self.update_settings(settings, update_builder),
Facets(levels) => self.update_facets(levels, update_builder),
};

View File

@ -33,6 +33,7 @@ pub struct IndexMetadata {
pub enum UpdateMeta {
DocumentsAddition { method: IndexDocumentsMethod, format: UpdateFormat },
ClearDocuments,
DeleteDocuments,
Settings(Settings),
Facets(Facets),
}
@ -94,6 +95,7 @@ impl Settings {
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum UpdateResult {
DocumentsAddition(DocumentAdditionResult),
DocumentDeletion { deleted: usize },
Other,
}
@ -131,6 +133,9 @@ pub trait IndexController {
/// Clear all documents in the given index.
fn clear_documents(&self, index: impl AsRef<str>) -> anyhow::Result<UpdateStatus>;
/// Clear all documents in the given index.
fn delete_documents(&self, index: impl AsRef<str>, document_ids: Vec<String>) -> anyhow::Result<UpdateStatus>;
/// Updates an index settings. If the index does not exist, it will be created when the update
/// is applied to the index.
fn update_settings<S: AsRef<str>>(&self, index_uid: S, settings: Settings) -> anyhow::Result<UpdateStatus>;

View File

@ -160,11 +160,25 @@ async fn update_documents(
wrap = "Authentication::Private"
)]
async fn delete_documents(
_data: web::Data<Data>,
_path: web::Path<IndexParam>,
_body: web::Json<Vec<Value>>,
data: web::Data<Data>,
path: web::Path<IndexParam>,
body: web::Json<Vec<Value>>,
) -> Result<HttpResponse, ResponseError> {
todo!()
let ids = body
.iter()
.map(ToString::to_string)
.collect();
match data.delete_documents(&path.index_uid, ids).await {
Ok(result) => {
let json = serde_json::to_string(&result).unwrap();
Ok(HttpResponse::Ok().body(json))
}
Err(e) => {
error!("{}", e);
unimplemented!()
}
}
}
#[delete("/indexes/{index_uid}/documents", wrap = "Authentication::Private")]