mirror of
https://github.com/meilisearch/meilisearch.git
synced 2025-09-05 20:26:31 +00:00
Add index rename feature
This commit is contained in:
@ -526,6 +526,20 @@ impl IndexMapper {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Rename an index.
|
||||||
|
pub fn rename(&self, wtxn: &mut RwTxn, current: &str, new: &str) -> Result<()> {
|
||||||
|
let uuid = self
|
||||||
|
.index_mapping
|
||||||
|
.get(wtxn, current)?
|
||||||
|
.ok_or_else(|| Error::IndexNotFound(current.to_string()))?;
|
||||||
|
if self.index_mapping.get(wtxn, new)?.is_some() {
|
||||||
|
return Err(Error::IndexAlreadyExists(new.to_string()));
|
||||||
|
}
|
||||||
|
self.index_mapping.delete(wtxn, current)?;
|
||||||
|
self.index_mapping.put(wtxn, new, &uuid)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// The stats of an index.
|
/// The stats of an index.
|
||||||
///
|
///
|
||||||
/// If available in the cache, they are directly returned.
|
/// If available in the cache, they are directly returned.
|
||||||
|
@ -125,6 +125,12 @@ make_enum_progress! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
make_enum_progress! {
|
||||||
|
pub enum RenameIndexProgress {
|
||||||
|
RenamingTheIndex,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
make_enum_progress! {
|
make_enum_progress! {
|
||||||
pub enum DeleteIndexProgress {
|
pub enum DeleteIndexProgress {
|
||||||
DeletingTheIndex,
|
DeletingTheIndex,
|
||||||
|
@ -24,6 +24,7 @@ enum AutobatchKind {
|
|||||||
IndexCreation,
|
IndexCreation,
|
||||||
IndexDeletion,
|
IndexDeletion,
|
||||||
IndexUpdate,
|
IndexUpdate,
|
||||||
|
IndexRename,
|
||||||
IndexSwap,
|
IndexSwap,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +68,7 @@ impl From<KindWithContent> for AutobatchKind {
|
|||||||
KindWithContent::IndexDeletion { .. } => AutobatchKind::IndexDeletion,
|
KindWithContent::IndexDeletion { .. } => AutobatchKind::IndexDeletion,
|
||||||
KindWithContent::IndexCreation { .. } => AutobatchKind::IndexCreation,
|
KindWithContent::IndexCreation { .. } => AutobatchKind::IndexCreation,
|
||||||
KindWithContent::IndexUpdate { .. } => AutobatchKind::IndexUpdate,
|
KindWithContent::IndexUpdate { .. } => AutobatchKind::IndexUpdate,
|
||||||
|
KindWithContent::IndexRename { .. } => AutobatchKind::IndexRename,
|
||||||
KindWithContent::IndexSwap { .. } => AutobatchKind::IndexSwap,
|
KindWithContent::IndexSwap { .. } => AutobatchKind::IndexSwap,
|
||||||
KindWithContent::TaskCancelation { .. }
|
KindWithContent::TaskCancelation { .. }
|
||||||
| KindWithContent::TaskDeletion { .. }
|
| KindWithContent::TaskDeletion { .. }
|
||||||
@ -115,6 +117,9 @@ pub enum BatchKind {
|
|||||||
IndexUpdate {
|
IndexUpdate {
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
},
|
},
|
||||||
|
IndexRename {
|
||||||
|
id: TaskId,
|
||||||
|
},
|
||||||
IndexSwap {
|
IndexSwap {
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
},
|
},
|
||||||
@ -176,6 +181,13 @@ impl BatchKind {
|
|||||||
)),
|
)),
|
||||||
false,
|
false,
|
||||||
),
|
),
|
||||||
|
K::IndexRename => (
|
||||||
|
Break((
|
||||||
|
BatchKind::IndexRename { id: task_id },
|
||||||
|
BatchStopReason::TaskCannotBeBatched { kind, id: task_id },
|
||||||
|
)),
|
||||||
|
false,
|
||||||
|
),
|
||||||
K::IndexSwap => (
|
K::IndexSwap => (
|
||||||
Break((
|
Break((
|
||||||
BatchKind::IndexSwap { id: task_id },
|
BatchKind::IndexSwap { id: task_id },
|
||||||
@ -288,7 +300,7 @@ impl BatchKind {
|
|||||||
|
|
||||||
match (self, autobatch_kind) {
|
match (self, autobatch_kind) {
|
||||||
// We don't batch any of these operations
|
// We don't batch any of these operations
|
||||||
(this, K::IndexCreation | K::IndexUpdate | K::IndexSwap | K::DocumentEdition) => Break((this, BatchStopReason::TaskCannotBeBatched { kind, id })),
|
(this, K::IndexCreation | K::IndexUpdate | K::IndexRename | K::IndexSwap | K::DocumentEdition) => Break((this, BatchStopReason::TaskCannotBeBatched { kind, id })),
|
||||||
// We must not batch tasks that don't have the same index creation rights if the index doesn't already exists.
|
// We must not batch tasks that don't have the same index creation rights if the index doesn't already exists.
|
||||||
(this, kind) if !index_already_exists && this.allow_index_creation() == Some(false) && kind.allow_index_creation() == Some(true) => {
|
(this, kind) if !index_already_exists && this.allow_index_creation() == Some(false) && kind.allow_index_creation() == Some(true) => {
|
||||||
Break((this, BatchStopReason::IndexCreationMismatch { id }))
|
Break((this, BatchStopReason::IndexCreationMismatch { id }))
|
||||||
|
@ -40,6 +40,11 @@ pub(crate) enum Batch {
|
|||||||
primary_key: Option<String>,
|
primary_key: Option<String>,
|
||||||
task: Task,
|
task: Task,
|
||||||
},
|
},
|
||||||
|
IndexRename {
|
||||||
|
index_uid: String,
|
||||||
|
new_index_uid: String,
|
||||||
|
task: Task,
|
||||||
|
},
|
||||||
IndexDeletion {
|
IndexDeletion {
|
||||||
index_uid: String,
|
index_uid: String,
|
||||||
tasks: Vec<Task>,
|
tasks: Vec<Task>,
|
||||||
@ -108,7 +113,8 @@ impl Batch {
|
|||||||
| Batch::Dump(task)
|
| Batch::Dump(task)
|
||||||
| Batch::IndexCreation { task, .. }
|
| Batch::IndexCreation { task, .. }
|
||||||
| Batch::Export { task }
|
| Batch::Export { task }
|
||||||
| Batch::IndexUpdate { task, .. } => {
|
| Batch::IndexUpdate { task, .. }
|
||||||
|
| Batch::IndexRename { task, .. } => {
|
||||||
RoaringBitmap::from_sorted_iter(std::iter::once(task.uid)).unwrap()
|
RoaringBitmap::from_sorted_iter(std::iter::once(task.uid)).unwrap()
|
||||||
}
|
}
|
||||||
Batch::SnapshotCreation(tasks)
|
Batch::SnapshotCreation(tasks)
|
||||||
@ -153,6 +159,7 @@ impl Batch {
|
|||||||
IndexOperation { op, .. } => Some(op.index_uid()),
|
IndexOperation { op, .. } => Some(op.index_uid()),
|
||||||
IndexCreation { index_uid, .. }
|
IndexCreation { index_uid, .. }
|
||||||
| IndexUpdate { index_uid, .. }
|
| IndexUpdate { index_uid, .. }
|
||||||
|
| IndexRename { index_uid, .. }
|
||||||
| IndexDeletion { index_uid, .. } => Some(index_uid),
|
| IndexDeletion { index_uid, .. } => Some(index_uid),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -171,6 +178,7 @@ impl fmt::Display for Batch {
|
|||||||
Batch::IndexOperation { op, .. } => write!(f, "{op}")?,
|
Batch::IndexOperation { op, .. } => write!(f, "{op}")?,
|
||||||
Batch::IndexCreation { .. } => f.write_str("IndexCreation")?,
|
Batch::IndexCreation { .. } => f.write_str("IndexCreation")?,
|
||||||
Batch::IndexUpdate { .. } => f.write_str("IndexUpdate")?,
|
Batch::IndexUpdate { .. } => f.write_str("IndexUpdate")?,
|
||||||
|
Batch::IndexRename { .. } => f.write_str("IndexRename")?,
|
||||||
Batch::IndexDeletion { .. } => f.write_str("IndexDeletion")?,
|
Batch::IndexDeletion { .. } => f.write_str("IndexDeletion")?,
|
||||||
Batch::IndexSwap { .. } => f.write_str("IndexSwap")?,
|
Batch::IndexSwap { .. } => f.write_str("IndexSwap")?,
|
||||||
Batch::Export { .. } => f.write_str("Export")?,
|
Batch::Export { .. } => f.write_str("Export")?,
|
||||||
@ -411,6 +419,16 @@ impl IndexScheduler {
|
|||||||
};
|
};
|
||||||
Ok(Some(Batch::IndexUpdate { index_uid, primary_key, task }))
|
Ok(Some(Batch::IndexUpdate { index_uid, primary_key, task }))
|
||||||
}
|
}
|
||||||
|
BatchKind::IndexRename { id } => {
|
||||||
|
let mut task =
|
||||||
|
self.queue.tasks.get_task(rtxn, id)?.ok_or(Error::CorruptedTaskQueue)?;
|
||||||
|
current_batch.processing(Some(&mut task));
|
||||||
|
let (new_uid) = match &task.kind {
|
||||||
|
KindWithContent::IndexRename { new_index_uid, .. } => new_index_uid.clone(),
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
Ok(Some(Batch::IndexRename { index_uid, new_index_uid: new_uid, task }))
|
||||||
|
}
|
||||||
BatchKind::IndexDeletion { ids } => Ok(Some(Batch::IndexDeletion {
|
BatchKind::IndexDeletion { ids } => Ok(Some(Batch::IndexDeletion {
|
||||||
index_uid,
|
index_uid,
|
||||||
index_has_been_created: must_create_index,
|
index_has_been_created: must_create_index,
|
||||||
|
@ -15,7 +15,7 @@ use super::create_batch::Batch;
|
|||||||
use crate::processing::{
|
use crate::processing::{
|
||||||
AtomicBatchStep, AtomicTaskStep, CreateIndexProgress, DeleteIndexProgress, FinalizingIndexStep,
|
AtomicBatchStep, AtomicTaskStep, CreateIndexProgress, DeleteIndexProgress, FinalizingIndexStep,
|
||||||
InnerSwappingTwoIndexes, SwappingTheIndexes, TaskCancelationProgress, TaskDeletionProgress,
|
InnerSwappingTwoIndexes, SwappingTheIndexes, TaskCancelationProgress, TaskDeletionProgress,
|
||||||
UpdateIndexProgress,
|
UpdateIndexProgress, RenameIndexProgress,
|
||||||
};
|
};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
self, remove_n_tasks_datetime_earlier_than, remove_task_datetime, swap_index_uid_in_task,
|
self, remove_n_tasks_datetime_earlier_than, remove_task_datetime, swap_index_uid_in_task,
|
||||||
@ -229,6 +229,20 @@ impl IndexScheduler {
|
|||||||
progress,
|
progress,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
Batch::IndexRename { index_uid, new_index_uid, mut task } => {
|
||||||
|
progress.update_progress(RenameIndexProgress::RenamingTheIndex);
|
||||||
|
let mut wtxn = self.env.write_txn()?;
|
||||||
|
self.index_mapper.rename(&mut wtxn, &index_uid, &new_index_uid)?;
|
||||||
|
self.queue.tasks.update_index(&mut wtxn, &new_index_uid, |bm| {
|
||||||
|
let old = self.queue.tasks.index_tasks(&wtxn, &index_uid).unwrap_or_default();
|
||||||
|
*bm |= &old;
|
||||||
|
})?;
|
||||||
|
self.queue.tasks.update_index(&mut wtxn, &index_uid, |bm| bm.clear())?;
|
||||||
|
wtxn.commit()?;
|
||||||
|
task.status = Status::Succeeded;
|
||||||
|
task.details = Some(Details::IndexRename(IndexRenameDetails { old_uid: index_uid, new_uid: new_index_uid }));
|
||||||
|
Ok((vec![task], ProcessBatchInfo::default()))
|
||||||
|
}
|
||||||
Batch::IndexUpdate { index_uid, primary_key, mut task } => {
|
Batch::IndexUpdate { index_uid, primary_key, mut task } => {
|
||||||
progress.update_progress(UpdateIndexProgress::UpdatingTheIndex);
|
progress.update_progress(UpdateIndexProgress::UpdatingTheIndex);
|
||||||
let rtxn = self.env.read_txn()?;
|
let rtxn = self.env.read_txn()?;
|
||||||
|
@ -141,6 +141,10 @@ pub enum KindWithContent {
|
|||||||
index_uid: String,
|
index_uid: String,
|
||||||
primary_key: Option<String>,
|
primary_key: Option<String>,
|
||||||
},
|
},
|
||||||
|
IndexRename {
|
||||||
|
index_uid: String,
|
||||||
|
new_index_uid: String,
|
||||||
|
},
|
||||||
IndexSwap {
|
IndexSwap {
|
||||||
swaps: Vec<IndexSwap>,
|
swaps: Vec<IndexSwap>,
|
||||||
},
|
},
|
||||||
@ -174,6 +178,13 @@ pub struct IndexSwap {
|
|||||||
pub indexes: (String, String),
|
pub indexes: (String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct IndexRenameDetails {
|
||||||
|
pub old_uid: String,
|
||||||
|
pub new_uid: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
#[derive(Debug, Default, Clone, PartialEq, Eq, Serialize, Deserialize, ToSchema)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ExportIndexSettings {
|
pub struct ExportIndexSettings {
|
||||||
@ -193,6 +204,7 @@ impl KindWithContent {
|
|||||||
KindWithContent::IndexCreation { .. } => Kind::IndexCreation,
|
KindWithContent::IndexCreation { .. } => Kind::IndexCreation,
|
||||||
KindWithContent::IndexDeletion { .. } => Kind::IndexDeletion,
|
KindWithContent::IndexDeletion { .. } => Kind::IndexDeletion,
|
||||||
KindWithContent::IndexUpdate { .. } => Kind::IndexUpdate,
|
KindWithContent::IndexUpdate { .. } => Kind::IndexUpdate,
|
||||||
|
KindWithContent::IndexRename { .. } => Kind::IndexRename,
|
||||||
KindWithContent::IndexSwap { .. } => Kind::IndexSwap,
|
KindWithContent::IndexSwap { .. } => Kind::IndexSwap,
|
||||||
KindWithContent::TaskCancelation { .. } => Kind::TaskCancelation,
|
KindWithContent::TaskCancelation { .. } => Kind::TaskCancelation,
|
||||||
KindWithContent::TaskDeletion { .. } => Kind::TaskDeletion,
|
KindWithContent::TaskDeletion { .. } => Kind::TaskDeletion,
|
||||||
@ -222,6 +234,7 @@ impl KindWithContent {
|
|||||||
| IndexCreation { index_uid, .. }
|
| IndexCreation { index_uid, .. }
|
||||||
| IndexUpdate { index_uid, .. }
|
| IndexUpdate { index_uid, .. }
|
||||||
| IndexDeletion { index_uid } => vec![index_uid],
|
| IndexDeletion { index_uid } => vec![index_uid],
|
||||||
|
IndexRename { index_uid, new_index_uid } => vec![index_uid, new_index_uid],
|
||||||
IndexSwap { swaps } => {
|
IndexSwap { swaps } => {
|
||||||
let mut indexes = HashSet::<&str>::default();
|
let mut indexes = HashSet::<&str>::default();
|
||||||
for swap in swaps {
|
for swap in swaps {
|
||||||
@ -274,6 +287,12 @@ impl KindWithContent {
|
|||||||
| KindWithContent::IndexUpdate { primary_key, .. } => {
|
| KindWithContent::IndexUpdate { primary_key, .. } => {
|
||||||
Some(Details::IndexInfo { primary_key: primary_key.clone() })
|
Some(Details::IndexInfo { primary_key: primary_key.clone() })
|
||||||
}
|
}
|
||||||
|
KindWithContent::IndexRename { index_uid, new_index_uid } => {
|
||||||
|
Some(Details::IndexRename {
|
||||||
|
old_uid: index_uid.clone(),
|
||||||
|
new_uid: new_index_uid.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
KindWithContent::IndexSwap { swaps } => {
|
KindWithContent::IndexSwap { swaps } => {
|
||||||
Some(Details::IndexSwap { swaps: swaps.clone() })
|
Some(Details::IndexSwap { swaps: swaps.clone() })
|
||||||
}
|
}
|
||||||
@ -344,6 +363,12 @@ impl KindWithContent {
|
|||||||
Some(Details::SettingsUpdate { settings: new_settings.clone() })
|
Some(Details::SettingsUpdate { settings: new_settings.clone() })
|
||||||
}
|
}
|
||||||
KindWithContent::IndexDeletion { .. } => None,
|
KindWithContent::IndexDeletion { .. } => None,
|
||||||
|
KindWithContent::IndexRename { index_uid, new_index_uid } => {
|
||||||
|
Some(Details::IndexRename {
|
||||||
|
old_uid: index_uid.clone(),
|
||||||
|
new_uid: new_index_uid.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
KindWithContent::IndexCreation { primary_key, .. }
|
KindWithContent::IndexCreation { primary_key, .. }
|
||||||
| KindWithContent::IndexUpdate { primary_key, .. } => {
|
| KindWithContent::IndexUpdate { primary_key, .. } => {
|
||||||
Some(Details::IndexInfo { primary_key: primary_key.clone() })
|
Some(Details::IndexInfo { primary_key: primary_key.clone() })
|
||||||
@ -538,6 +563,7 @@ pub enum Kind {
|
|||||||
IndexCreation,
|
IndexCreation,
|
||||||
IndexDeletion,
|
IndexDeletion,
|
||||||
IndexUpdate,
|
IndexUpdate,
|
||||||
|
IndexRename,
|
||||||
IndexSwap,
|
IndexSwap,
|
||||||
TaskCancelation,
|
TaskCancelation,
|
||||||
TaskDeletion,
|
TaskDeletion,
|
||||||
@ -556,7 +582,8 @@ impl Kind {
|
|||||||
| Kind::SettingsUpdate
|
| Kind::SettingsUpdate
|
||||||
| Kind::IndexCreation
|
| Kind::IndexCreation
|
||||||
| Kind::IndexDeletion
|
| Kind::IndexDeletion
|
||||||
| Kind::IndexUpdate => true,
|
| Kind::IndexUpdate
|
||||||
|
| Kind::IndexRename => true,
|
||||||
Kind::IndexSwap
|
Kind::IndexSwap
|
||||||
| Kind::TaskCancelation
|
| Kind::TaskCancelation
|
||||||
| Kind::TaskDeletion
|
| Kind::TaskDeletion
|
||||||
@ -577,6 +604,7 @@ impl Display for Kind {
|
|||||||
Kind::IndexCreation => write!(f, "indexCreation"),
|
Kind::IndexCreation => write!(f, "indexCreation"),
|
||||||
Kind::IndexDeletion => write!(f, "indexDeletion"),
|
Kind::IndexDeletion => write!(f, "indexDeletion"),
|
||||||
Kind::IndexUpdate => write!(f, "indexUpdate"),
|
Kind::IndexUpdate => write!(f, "indexUpdate"),
|
||||||
|
Kind::IndexRename => write!(f, "indexRename"),
|
||||||
Kind::IndexSwap => write!(f, "indexSwap"),
|
Kind::IndexSwap => write!(f, "indexSwap"),
|
||||||
Kind::TaskCancelation => write!(f, "taskCancelation"),
|
Kind::TaskCancelation => write!(f, "taskCancelation"),
|
||||||
Kind::TaskDeletion => write!(f, "taskDeletion"),
|
Kind::TaskDeletion => write!(f, "taskDeletion"),
|
||||||
@ -595,6 +623,8 @@ impl FromStr for Kind {
|
|||||||
Ok(Kind::IndexCreation)
|
Ok(Kind::IndexCreation)
|
||||||
} else if kind.eq_ignore_ascii_case("indexUpdate") {
|
} else if kind.eq_ignore_ascii_case("indexUpdate") {
|
||||||
Ok(Kind::IndexUpdate)
|
Ok(Kind::IndexUpdate)
|
||||||
|
} else if kind.eq_ignore_ascii_case("indexRename") {
|
||||||
|
Ok(Kind::IndexRename)
|
||||||
} else if kind.eq_ignore_ascii_case("indexSwap") {
|
} else if kind.eq_ignore_ascii_case("indexSwap") {
|
||||||
Ok(Kind::IndexSwap)
|
Ok(Kind::IndexSwap)
|
||||||
} else if kind.eq_ignore_ascii_case("indexDeletion") {
|
} else if kind.eq_ignore_ascii_case("indexDeletion") {
|
||||||
@ -692,6 +722,7 @@ pub enum Details {
|
|||||||
IndexSwap {
|
IndexSwap {
|
||||||
swaps: Vec<IndexSwap>,
|
swaps: Vec<IndexSwap>,
|
||||||
},
|
},
|
||||||
|
IndexRename(IndexRenameDetails),
|
||||||
Export {
|
Export {
|
||||||
url: String,
|
url: String,
|
||||||
api_key: Option<String>,
|
api_key: Option<String>,
|
||||||
@ -737,6 +768,7 @@ impl Details {
|
|||||||
Self::SettingsUpdate { .. }
|
Self::SettingsUpdate { .. }
|
||||||
| Self::IndexInfo { .. }
|
| Self::IndexInfo { .. }
|
||||||
| Self::Dump { .. }
|
| Self::Dump { .. }
|
||||||
|
| Self::IndexRename { .. }
|
||||||
| Self::Export { .. }
|
| Self::Export { .. }
|
||||||
| Self::UpgradeDatabase { .. }
|
| Self::UpgradeDatabase { .. }
|
||||||
| Self::IndexSwap { .. } => (),
|
| Self::IndexSwap { .. } => (),
|
||||||
|
Reference in New Issue
Block a user