Skip to content

Commit f27198f

Browse files
authored
Index update from index config (quickwit-oss#5078)
* Add indexing_settings and use index config as input * Doc fixes and cleanup deprecated parameters * Doc improvments * Fix outdated IndexMetadata content * Fix typos in CLI output * Add metastore tests for each updatable config field * Address review comments * Fix unintended privatisation of DocMapping * Fix typo in tests * Address review comments
1 parent 82a00a7 commit f27198f

File tree

26 files changed

+772
-609
lines changed

26 files changed

+772
-609
lines changed

config/tutorials/hdfs-logs/index-config-partitioned.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,3 @@ indexing_settings:
4343
merge_factor: 10
4444
max_merge_ops: 3
4545
maturation_period: 48 hours
46-
resources:
47-
max_merge_write_throughput: 100mb

docs/reference/cli.md

Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -182,49 +182,23 @@ quickwit index create --endpoint=http://127.0.0.1:7280 --index-config wikipedia_
182182

183183
### index update
184184

185+
Updates an index using an index config file.
185186
`quickwit index update [args]`
186-
#### index update search-settings
187-
188-
Updates default search settings.
189-
`quickwit index update search-settings [args]`
190187

191188
*Synopsis*
192189

193190
```bash
194-
quickwit index update search-settings
191+
quickwit index update
195192
--index <index>
196-
--default-search-fields <default-search-fields>
197-
```
198-
199-
*Options*
200-
201-
| Option | Description |
202-
|-----------------|-------------|
203-
| `--index` | ID of the target index |
204-
| `--default-search-fields` | List of fields that Quickwit will search into if the user query does not explicitly target a field. Space-separated list, e.g. "field1 field2". If no value is provided, existing defaults are removed and queries without target field will fail. |
205-
#### index update retention-policy
206-
207-
Configure or disable the retention policy.
208-
`quickwit index update retention-policy [args]`
209-
210-
*Synopsis*
211-
212-
```bash
213-
quickwit index update retention-policy
214-
--index <index>
215-
[--period <period>]
216-
[--schedule <schedule>]
217-
[--disable]
193+
--index-config <index-config>
218194
```
219195

220196
*Options*
221197

222198
| Option | Description |
223199
|-----------------|-------------|
224200
| `--index` | ID of the target index |
225-
| `--period` | Duration after which splits are dropped. Expressed in a human-readable way (`1 day`, `2 hours`, `1 week`, ...) |
226-
| `--schedule` | Frequency at which the retention policy is evaluated and applied. Expressed as a cron expression (0 0 * * * *) or human-readable form (hourly, daily, weekly, ...). |
227-
| `--disable` | Disable the retention policy. Old indexed data will not be cleaned up anymore. |
201+
| `--index-config` | Location of the index config file. |
228202
### index clear
229203

230204
Clears an index: deletes all splits and resets checkpoint.
@@ -381,7 +355,7 @@ quickwit index ingest
381355
| `--batch-size-limit` | Size limit of each submitted document batch. |
382356
| `--wait` | Wait for all documents to be commited and available for search before exiting |
383357
| `--force` | Force a commit after the last document is sent, and wait for all documents to be committed and available for search before exiting |
384-
| `--commit-timeout` | Timeout for ingest operations that require waiting for the final commit (`--wait` or `--force`). This is different from the `commit_timeout_secs` indexing setting which sets the maximum time before commiting splits after their creation. |
358+
| `--commit-timeout` | Timeout for ingest operations that require waiting for the final commit (`--wait` or `--force`). This is different from the `commit_timeout_secs` indexing setting, which sets the maximum time before commiting splits after their creation. |
385359

386360
*Examples*
387361

docs/reference/rest-api.md

Lines changed: 104 additions & 62 deletions
Large diffs are not rendered by default.

quickwit/quickwit-cli/src/index/mod.rs renamed to quickwit/quickwit-cli/src/index.rs

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,13 +57,10 @@ use tabled::{Table, Tabled};
5757
use thousands::Separable;
5858
use tracing::{debug, Level};
5959

60-
use self::update::{build_index_update_command, IndexUpdateCliCommand};
6160
use crate::checklist::GREEN_COLOR;
6261
use crate::stats::{mean, percentile, std_deviation};
6362
use crate::{client_args, make_table, prompt_confirmation, ClientArgs, THROUGHPUT_WINDOW_SIZE};
6463

65-
pub mod update;
66-
6764
pub fn build_index_command() -> Command {
6865
Command::new("index")
6966
.about("Manages indexes: creates, updates, deletes, ingests, searches, describes...")
@@ -81,7 +78,18 @@ pub fn build_index_command() -> Command {
8178
])
8279
)
8380
.subcommand(
84-
build_index_update_command().display_order(2)
81+
Command::new("update")
82+
.display_order(1)
83+
.about("Updates an index using an index config file.")
84+
.long_about("This command follows PUT semantics, which means that all the fields of the current configuration are replaced by the values specified in this request or the associated defaults. In particular, if the field is optional (e.g. `retention_policy`), omitting it will delete the associated configuration. If the new configuration file contains updates that cannot be applied, the request fails, and none of the updates are applied.")
85+
.args(&[
86+
arg!(--index <INDEX> "ID of the target index")
87+
.display_order(1)
88+
.required(true),
89+
arg!(--"index-config" <INDEX_CONFIG> "Location of the index config file.")
90+
.display_order(2)
91+
.required(true),
92+
])
8593
)
8694
.subcommand(
8795
Command::new("clear")
@@ -213,6 +221,14 @@ pub struct CreateIndexArgs {
213221
pub assume_yes: bool,
214222
}
215223

224+
#[derive(Debug, Eq, PartialEq)]
225+
pub struct UpdateIndexArgs {
226+
pub client_args: ClientArgs,
227+
pub index_id: IndexId,
228+
pub index_config_uri: Uri,
229+
pub assume_yes: bool,
230+
}
231+
216232
#[derive(Debug, Eq, PartialEq)]
217233
pub struct DescribeIndexArgs {
218234
pub client_args: ClientArgs,
@@ -260,12 +276,12 @@ pub struct ListIndexesArgs {
260276
pub enum IndexCliCommand {
261277
Clear(ClearIndexArgs),
262278
Create(CreateIndexArgs),
279+
Update(UpdateIndexArgs),
263280
Delete(DeleteIndexArgs),
264281
Describe(DescribeIndexArgs),
265282
Ingest(IngestDocsArgs),
266283
List(ListIndexesArgs),
267284
Search(SearchIndexArgs),
268-
Update(IndexUpdateCliCommand),
269285
}
270286

271287
impl IndexCliCommand {
@@ -288,7 +304,7 @@ impl IndexCliCommand {
288304
"ingest" => Self::parse_ingest_args(submatches),
289305
"list" => Self::parse_list_args(submatches),
290306
"search" => Self::parse_search_args(submatches),
291-
"update" => Ok(Self::Update(IndexUpdateCliCommand::parse_args(submatches)?)),
307+
"update" => Self::parse_update_args(submatches),
292308
_ => bail!("unknown index subcommand `{subcommand}`"),
293309
}
294310
}
@@ -323,6 +339,25 @@ impl IndexCliCommand {
323339
}))
324340
}
325341

342+
fn parse_update_args(mut matches: ArgMatches) -> anyhow::Result<Self> {
343+
let client_args = ClientArgs::parse(&mut matches)?;
344+
let index_id = matches
345+
.remove_one::<String>("index")
346+
.expect("`index` should be a required arg.");
347+
let index_config_uri = matches
348+
.remove_one::<String>("index-config")
349+
.map(|uri| Uri::from_str(&uri))
350+
.expect("`index-config` should be a required arg.")?;
351+
let assume_yes = matches.get_flag("yes");
352+
353+
Ok(Self::Update(UpdateIndexArgs {
354+
index_id,
355+
client_args,
356+
index_config_uri,
357+
assume_yes,
358+
}))
359+
}
360+
326361
fn parse_describe_args(mut matches: ArgMatches) -> anyhow::Result<Self> {
327362
let client_args = ClientArgs::parse(&mut matches)?;
328363
let index_id = matches
@@ -449,7 +484,7 @@ impl IndexCliCommand {
449484
Self::Ingest(args) => ingest_docs_cli(args).await,
450485
Self::List(args) => list_index_cli(args).await,
451486
Self::Search(args) => search_index_cli(args).await,
452-
Self::Update(args) => args.execute().await,
487+
Self::Update(args) => update_index_cli(args).await,
453488
}
454489
}
455490
}
@@ -501,6 +536,35 @@ pub async fn create_index_cli(args: CreateIndexArgs) -> anyhow::Result<()> {
501536
Ok(())
502537
}
503538

539+
pub async fn update_index_cli(args: UpdateIndexArgs) -> anyhow::Result<()> {
540+
debug!(args=?args, "update-index");
541+
println!("❯ Updating index...");
542+
let storage_resolver = StorageResolver::unconfigured();
543+
let file_content = load_file(&storage_resolver, &args.index_config_uri).await?;
544+
let index_config_str = std::str::from_utf8(&file_content)
545+
.with_context(|| {
546+
format!(
547+
"index config file `{}` contains some invalid UTF-8 characters",
548+
args.index_config_uri
549+
)
550+
})?
551+
.to_string();
552+
let config_format = ConfigFormat::sniff_from_uri(&args.index_config_uri)?;
553+
let qw_client = args.client_args.client();
554+
if !args.assume_yes {
555+
let prompt = "This operation will update the index configuration. Do you want to proceed?";
556+
if !prompt_confirmation(prompt, false) {
557+
return Ok(());
558+
}
559+
}
560+
qw_client
561+
.indexes()
562+
.update(&args.index_id, &index_config_str, config_format)
563+
.await?;
564+
println!("{} Index successfully updated.", "✔".color(GREEN_COLOR));
565+
Ok(())
566+
}
567+
504568
pub async fn list_index_cli(args: ListIndexesArgs) -> anyhow::Result<()> {
505569
debug!(args=?args, "list-index");
506570
let qw_client = args.client_args.client();

0 commit comments

Comments
 (0)