mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-01 19:08:29 +02:00
Merge b853de958460607005e847734874563544b6fb1d into 904b82a61d1f1ab8e1c67be92544fa19f5c50811
This commit is contained in:
commit
faa3d466b4
@ -32,7 +32,7 @@ fn setup_index() -> Index {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
options.max_readers(10);
|
options.max_readers(10);
|
||||||
Index::new(options, path).unwrap()
|
Index::new(None, options, path).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_settings<'t>(
|
fn setup_settings<'t>(
|
||||||
|
@ -66,7 +66,7 @@ pub fn base_setup(conf: &Conf) -> Index {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
options.max_readers(10);
|
options.max_readers(10);
|
||||||
let index = Index::new(options, conf.database_name).unwrap();
|
let index = Index::new(None, options, conf.database_name).unwrap();
|
||||||
|
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
|
@ -56,7 +56,7 @@ fn main() {
|
|||||||
Some(path) => TempDir::new_in(path).unwrap(),
|
Some(path) => TempDir::new_in(path).unwrap(),
|
||||||
None => TempDir::new().unwrap(),
|
None => TempDir::new().unwrap(),
|
||||||
};
|
};
|
||||||
let index = Index::new(options, tempdir.path()).unwrap();
|
let index = Index::new(None, options, tempdir.path()).unwrap();
|
||||||
let indexer_config = IndexerConfig::default();
|
let indexer_config = IndexerConfig::default();
|
||||||
let index_documents_config = IndexDocumentsConfig::default();
|
let index_documents_config = IndexDocumentsConfig::default();
|
||||||
|
|
||||||
|
@ -103,7 +103,7 @@ impl ReopenableIndex {
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
map.unavailable.remove(&self.uuid);
|
map.unavailable.remove(&self.uuid);
|
||||||
map.create(&self.uuid, path, None, self.enable_mdb_writemap, self.map_size)?;
|
map.create(None, &self.uuid, path, None, self.enable_mdb_writemap, self.map_size)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -167,6 +167,7 @@ impl IndexMap {
|
|||||||
///
|
///
|
||||||
pub fn create(
|
pub fn create(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
name: Option<String>,
|
||||||
uuid: &Uuid,
|
uuid: &Uuid,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
||||||
@ -176,7 +177,7 @@ impl IndexMap {
|
|||||||
if !matches!(self.get_unavailable(uuid), Missing) {
|
if !matches!(self.get_unavailable(uuid), Missing) {
|
||||||
panic!("Attempt to open an index that was unavailable");
|
panic!("Attempt to open an index that was unavailable");
|
||||||
}
|
}
|
||||||
let index = create_or_open_index(path, date, enable_mdb_writemap, map_size)?;
|
let index = create_or_open_index(name, path, date, enable_mdb_writemap, map_size)?;
|
||||||
match self.available.insert(*uuid, index.clone()) {
|
match self.available.insert(*uuid, index.clone()) {
|
||||||
InsertionOutcome::InsertedNew => (),
|
InsertionOutcome::InsertedNew => (),
|
||||||
InsertionOutcome::Evicted(evicted_uuid, evicted_index) => {
|
InsertionOutcome::Evicted(evicted_uuid, evicted_index) => {
|
||||||
@ -296,6 +297,7 @@ impl IndexMap {
|
|||||||
/// Create or open an index in the specified path.
|
/// Create or open an index in the specified path.
|
||||||
/// The path *must* exist or an error will be thrown.
|
/// The path *must* exist or an error will be thrown.
|
||||||
fn create_or_open_index(
|
fn create_or_open_index(
|
||||||
|
name: Option<String>,
|
||||||
path: &Path,
|
path: &Path,
|
||||||
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
date: Option<(OffsetDateTime, OffsetDateTime)>,
|
||||||
enable_mdb_writemap: bool,
|
enable_mdb_writemap: bool,
|
||||||
@ -309,9 +311,9 @@ fn create_or_open_index(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some((created, updated)) = date {
|
if let Some((created, updated)) = date {
|
||||||
Ok(Index::new_with_creation_dates(options, path, created, updated)?)
|
Ok(Index::new_with_creation_dates(name, options, path, created, updated)?)
|
||||||
} else {
|
} else {
|
||||||
Ok(Index::new(options, path)?)
|
Ok(Index::new(name, options, path)?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,6 +182,7 @@ impl IndexMapper {
|
|||||||
// This is very unlikely to happen in practice.
|
// This is very unlikely to happen in practice.
|
||||||
// TODO: it would be better to lazily create the index. But we need an Index::open function for milli.
|
// TODO: it would be better to lazily create the index. But we need an Index::open function for milli.
|
||||||
let index = self.index_map.write().unwrap().create(
|
let index = self.index_map.write().unwrap().create(
|
||||||
|
Some(name.to_string()),
|
||||||
&uuid,
|
&uuid,
|
||||||
&index_path,
|
&index_path,
|
||||||
date,
|
date,
|
||||||
@ -371,6 +372,7 @@ impl IndexMapper {
|
|||||||
let index_path = self.base_path.join(uuid.to_string());
|
let index_path = self.base_path.join(uuid.to_string());
|
||||||
|
|
||||||
break index_map.create(
|
break index_map.create(
|
||||||
|
Some(name.to_string()),
|
||||||
&uuid,
|
&uuid,
|
||||||
&index_path,
|
&index_path,
|
||||||
None,
|
None,
|
||||||
|
@ -282,6 +282,9 @@ pub struct IndexSchedulerOptions {
|
|||||||
/// Structure which holds meilisearch's indexes and schedules the tasks
|
/// Structure which holds meilisearch's indexes and schedules the tasks
|
||||||
/// to be performed on them.
|
/// to be performed on them.
|
||||||
pub struct IndexScheduler {
|
pub struct IndexScheduler {
|
||||||
|
/// A String representing the name of the index
|
||||||
|
pub(crate) name: String,
|
||||||
|
|
||||||
/// The LMDB environment which the DBs are associated with.
|
/// The LMDB environment which the DBs are associated with.
|
||||||
pub(crate) env: Env,
|
pub(crate) env: Env,
|
||||||
|
|
||||||
|
@ -882,7 +882,7 @@ async fn sort_unsortable_attribute() {
|
|||||||
index.wait_task(1).await;
|
index.wait_task(1).await;
|
||||||
|
|
||||||
let expected_response = json!({
|
let expected_response = json!({
|
||||||
"message": "Attribute `title` is not sortable. Available sortable attributes are: `id`.",
|
"message": "Attribute `title` of index `test` is not sortable. Available sortable attributes are: `id`.",
|
||||||
"code": "invalid_search_sort",
|
"code": "invalid_search_sort",
|
||||||
"type": "invalid_request",
|
"type": "invalid_request",
|
||||||
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
|
"link": "https://docs.meilisearch.com/errors#invalid_search_sort"
|
||||||
|
@ -267,7 +267,7 @@ fn export_a_dump(
|
|||||||
for result in index_mapping.iter(&rtxn)? {
|
for result in index_mapping.iter(&rtxn)? {
|
||||||
let (uid, uuid) = result?;
|
let (uid, uuid) = result?;
|
||||||
let index_path = db_path.join("indexes").join(uuid.to_string());
|
let index_path = db_path.join("indexes").join(uuid.to_string());
|
||||||
let index = Index::new(EnvOpenOptions::new(), &index_path).with_context(|| {
|
let index = Index::new(None, EnvOpenOptions::new(), &index_path).with_context(|| {
|
||||||
format!("While trying to open the index at path {:?}", index_path.display())
|
format!("While trying to open the index at path {:?}", index_path.display())
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
|
|
||||||
std::fs::create_dir_all(&index_path).unwrap();
|
std::fs::create_dir_all(&index_path).unwrap();
|
||||||
let index = Index::new(options, index_path).unwrap();
|
let index = Index::new(Some(program_name), options, index_path).unwrap();
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
|
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -28,7 +28,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
|
|
||||||
let index = Index::new(options, dataset)?;
|
let index = Index::new(Some(program_name), options, dataset)?;
|
||||||
let txn = index.read_txn()?;
|
let txn = index.read_txn()?;
|
||||||
let mut query = String::new();
|
let mut query = String::new();
|
||||||
while stdin().read_line(&mut query)? > 0 {
|
while stdin().read_line(&mut query)? > 0 {
|
||||||
|
@ -10,7 +10,7 @@ fn main() {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
options.map_size(100 * 1024 * 1024 * 1024); // 100 GB
|
||||||
|
|
||||||
let index = Index::new(options, "data_movies.ms").unwrap();
|
let index = Index::new(None, options, "data_movies.ms").unwrap();
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
|
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -122,8 +122,12 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco
|
|||||||
InvalidFilter(String),
|
InvalidFilter(String),
|
||||||
#[error("Invalid type for filter subexpression: expected: {}, found: {1}.", .0.join(", "))]
|
#[error("Invalid type for filter subexpression: expected: {}, found: {1}.", .0.join(", "))]
|
||||||
InvalidFilterExpression(&'static [&'static str], Value),
|
InvalidFilterExpression(&'static [&'static str], Value),
|
||||||
#[error("Attribute `{}` is not sortable. {}",
|
#[error("Attribute `{}`{} is not sortable. {}",
|
||||||
.field,
|
.field,
|
||||||
|
match .index_name.is_some() {
|
||||||
|
true => format!(" of index `{}`", index_name.clone().unwrap()),
|
||||||
|
false => String::from(""),
|
||||||
|
},
|
||||||
match .valid_fields.is_empty() {
|
match .valid_fields.is_empty() {
|
||||||
true => "This index does not have configured sortable attributes.".to_string(),
|
true => "This index does not have configured sortable attributes.".to_string(),
|
||||||
false => format!("Available sortable attributes are: `{}{}`.",
|
false => format!("Available sortable attributes are: `{}{}`.",
|
||||||
@ -132,7 +136,12 @@ only composed of alphanumeric characters (a-z A-Z 0-9), hyphens (-) and undersco
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
InvalidSortableAttribute { field: String, valid_fields: BTreeSet<String>, hidden_fields: bool },
|
InvalidSortableAttribute {
|
||||||
|
field: String,
|
||||||
|
index_name: Option<String>,
|
||||||
|
valid_fields: BTreeSet<String>,
|
||||||
|
hidden_fields: bool,
|
||||||
|
},
|
||||||
#[error("Attribute `{}` is not facet-searchable. {}",
|
#[error("Attribute `{}` is not facet-searchable. {}",
|
||||||
.field,
|
.field,
|
||||||
match .valid_fields.is_empty() {
|
match .valid_fields.is_empty() {
|
||||||
@ -451,7 +460,7 @@ impl std::fmt::Display for FaultSource {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn conditionally_lookup_for_error_message() {
|
fn conditionally_lookup_for_error_message() {
|
||||||
let prefix = "Attribute `name` is not sortable.";
|
let prefix = "Attribute `name` of index `index` is not sortable.";
|
||||||
let messages = vec![
|
let messages = vec![
|
||||||
(BTreeSet::new(), "This index does not have configured sortable attributes."),
|
(BTreeSet::new(), "This index does not have configured sortable attributes."),
|
||||||
(BTreeSet::from(["age".to_string()]), "Available sortable attributes are: `age`."),
|
(BTreeSet::from(["age".to_string()]), "Available sortable attributes are: `age`."),
|
||||||
@ -460,6 +469,7 @@ fn conditionally_lookup_for_error_message() {
|
|||||||
for (list, suffix) in messages {
|
for (list, suffix) in messages {
|
||||||
let err = UserError::InvalidSortableAttribute {
|
let err = UserError::InvalidSortableAttribute {
|
||||||
field: "name".to_string(),
|
field: "name".to_string(),
|
||||||
|
index_name: Some("index".to_string()),
|
||||||
valid_fields: list,
|
valid_fields: list,
|
||||||
hidden_fields: false,
|
hidden_fields: false,
|
||||||
};
|
};
|
||||||
|
@ -1548,7 +1548,7 @@ pub(crate) mod tests {
|
|||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(size);
|
options.map_size(size);
|
||||||
let _tempdir = TempDir::new_in(".").unwrap();
|
let _tempdir = TempDir::new_in(".").unwrap();
|
||||||
let inner = Index::new(options, _tempdir.path()).unwrap();
|
let inner = Index::new(Some("temp".to_string()), options, _tempdir.path()).unwrap();
|
||||||
let indexer_config = IndexerConfig::default();
|
let indexer_config = IndexerConfig::default();
|
||||||
let index_documents_config = IndexDocumentsConfig::default();
|
let index_documents_config = IndexDocumentsConfig::default();
|
||||||
Self { inner, indexer_config, index_documents_config, _tempdir }
|
Self { inner, indexer_config, index_documents_config, _tempdir }
|
||||||
|
@ -714,6 +714,7 @@ fn check_sort_criteria(ctx: &SearchContext, sort_criteria: Option<&Vec<AscDesc>>
|
|||||||
|
|
||||||
return Err(UserError::InvalidSortableAttribute {
|
return Err(UserError::InvalidSortableAttribute {
|
||||||
field: field.to_string(),
|
field: field.to_string(),
|
||||||
|
index_name: ctx.index.name.clone(),
|
||||||
valid_fields,
|
valid_fields,
|
||||||
hidden_fields,
|
hidden_fields,
|
||||||
}
|
}
|
||||||
@ -725,6 +726,7 @@ fn check_sort_criteria(ctx: &SearchContext, sort_criteria: Option<&Vec<AscDesc>>
|
|||||||
|
|
||||||
return Err(UserError::InvalidSortableAttribute {
|
return Err(UserError::InvalidSortableAttribute {
|
||||||
field: "_geo".to_string(),
|
field: "_geo".to_string(),
|
||||||
|
index_name: ctx.index.name.clone(),
|
||||||
valid_fields,
|
valid_fields,
|
||||||
hidden_fields,
|
hidden_fields,
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ pub fn setup_search_index_with_criteria(criteria: &[Criterion]) -> Index {
|
|||||||
let path = tempfile::tempdir().unwrap();
|
let path = tempfile::tempdir().unwrap();
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(10 * 1024 * 1024); // 10 MB
|
options.map_size(10 * 1024 * 1024); // 10 MB
|
||||||
let index = Index::new(options, &path).unwrap();
|
let index = Index::new(None, options, &path).unwrap();
|
||||||
|
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -25,6 +25,7 @@ impl<'t, 'i> ClearDocuments<'t, 'i> {
|
|||||||
|
|
||||||
self.index.set_updated_at(self.wtxn, &OffsetDateTime::now_utc())?;
|
self.index.set_updated_at(self.wtxn, &OffsetDateTime::now_utc())?;
|
||||||
let Index {
|
let Index {
|
||||||
|
name: _name,
|
||||||
env: _env,
|
env: _env,
|
||||||
main: _main,
|
main: _main,
|
||||||
external_documents_ids,
|
external_documents_ids,
|
||||||
|
@ -13,7 +13,7 @@ fn test_facet_distribution_with_no_facet_values() {
|
|||||||
let path = tempfile::tempdir().unwrap();
|
let path = tempfile::tempdir().unwrap();
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(10 * 1024 * 1024); // 10 MB
|
options.map_size(10 * 1024 * 1024); // 10 MB
|
||||||
let index = Index::new(options, &path).unwrap();
|
let index = Index::new(None, options, &path).unwrap();
|
||||||
|
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -31,7 +31,7 @@ pub fn setup_search_index_with_criteria(criteria: &[Criterion]) -> Index {
|
|||||||
let path = tempfile::tempdir().unwrap();
|
let path = tempfile::tempdir().unwrap();
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(10 * 1024 * 1024); // 10 MB
|
options.map_size(10 * 1024 * 1024); // 10 MB
|
||||||
let index = Index::new(options, &path).unwrap();
|
let index = Index::new(None, options, &path).unwrap();
|
||||||
|
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -262,7 +262,7 @@ fn criteria_ascdesc() {
|
|||||||
let path = tempfile::tempdir().unwrap();
|
let path = tempfile::tempdir().unwrap();
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(12 * 1024 * 1024); // 10 MB
|
options.map_size(12 * 1024 * 1024); // 10 MB
|
||||||
let index = Index::new(options, &path).unwrap();
|
let index = Index::new(None, options, &path).unwrap();
|
||||||
|
|
||||||
let mut wtxn = index.write_txn().unwrap();
|
let mut wtxn = index.write_txn().unwrap();
|
||||||
let config = IndexerConfig::default();
|
let config = IndexerConfig::default();
|
||||||
|
@ -104,7 +104,7 @@ fn test_typo_disabled_on_word() {
|
|||||||
let tmp = tempdir().unwrap();
|
let tmp = tempdir().unwrap();
|
||||||
let mut options = EnvOpenOptions::new();
|
let mut options = EnvOpenOptions::new();
|
||||||
options.map_size(4096 * 100);
|
options.map_size(4096 * 100);
|
||||||
let index = Index::new(options, tmp.path()).unwrap();
|
let index = Index::new(None, options, tmp.path()).unwrap();
|
||||||
|
|
||||||
let mut builder = milli::documents::DocumentsBatchBuilder::new(Vec::new());
|
let mut builder = milli::documents::DocumentsBatchBuilder::new(Vec::new());
|
||||||
let doc1 = json!({
|
let doc1 = json!({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user