Skip to content

Commit afabcf1

Browse files
authored
Merge branch 'main' into feat/attributes
2 parents b1bd536 + f0746ec commit afabcf1

File tree

8 files changed

+375
-4
lines changed

8 files changed

+375
-4
lines changed

.code-samples.meilisearch.yaml

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ get_documents_post_1: |-
142142
.execute::<Movies>()
143143
.await
144144
.unwrap();
145+
get_documents_by_ids_1: |-
146+
let index = client.index("books");
147+
let documents: DocumentsResults = DocumentsQuery::new(&index)
148+
.with_ids(["1", "2"]) // retrieve documents by IDs
149+
.execute::<Movies>()
150+
.await
151+
.unwrap();
145152
add_or_replace_documents_1: |-
146153
let task: TaskInfo = client
147154
.index("movies")
@@ -728,10 +735,16 @@ distinct_attribute_guide_1: |-
728735
.set_distinct_attribute("product_id")
729736
.await
730737
.unwrap();
738+
compact_index_1: |-
739+
let task: TaskInfo = client
740+
.index("INDEX_UID")
741+
.compact()
742+
.await
743+
.unwrap();
731744
field_properties_guide_searchable_1: |-
732745
let searchable_attributes = [
733746
"title",
734-
"overvieww",
747+
"overview",
735748
"genres"
736749
];
737750
@@ -743,7 +756,7 @@ field_properties_guide_searchable_1: |-
743756
field_properties_guide_displayed_1: |-
744757
let displayed_attributes = [
745758
"title",
746-
"overvieww",
759+
"overview",
747760
"genres",
748761
"release_date"
749762
];
@@ -1974,6 +1987,20 @@ search_parameter_reference_retrieve_vectors_1: |-
19741987
.execute()
19751988
.await
19761989
.unwrap();
1990+
search_parameter_reference_media_1: |-
1991+
let results = index
1992+
.search()
1993+
.with_hybrid("EMBEDDER_NAME", 0.5)
1994+
.with_media(json!({
1995+
"FIELD_A": "VALUE_A",
1996+
"FIELD_B": {
1997+
"FIELD_C": "VALUE_B",
1998+
"FIELD_D": "VALUE_C"
1999+
}
2000+
}))
2001+
.execute()
2002+
.await
2003+
.unwrap();
19772004
update_embedders_1: |-
19782005
let embedders = HashMap::from([(
19792006
String::from("default"),

examples/web_app_graphql/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ actix-web = "4.4.0"
1212
async-graphql = "6.0.11"
1313
async-graphql-actix-web = "6.0.11"
1414
diesel = { version = "2.1.4", features = ["postgres"] }
15-
diesel-async = { version = "0.6.1", features = ["postgres", "deadpool"] }
15+
diesel-async = { version = "0.7.3", features = ["postgres", "deadpool"] }
1616
diesel_migrations = "2.1.0"
1717
dotenvy = "0.15.7"
1818
env_logger = "0.11.3"

src/documents.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,15 @@ pub struct DocumentsQuery<'a, Http: HttpClient> {
202202
/// Read the [dedicated guide](https://www.meilisearch.com/docs/learn/filtering_and_sorting) to learn the syntax.
203203
#[serde(skip_serializing_if = "Option::is_none")]
204204
pub filter: Option<&'a str>,
205+
206+
/// Retrieve documents by their IDs.
207+
///
208+
/// When `ids` is provided, the SDK will call the `/documents/fetch` endpoint with a POST request.
209+
///
210+
/// Note: IDs are represented as strings to keep consistency with [`Index::get_document`]. If your IDs
211+
/// are numeric, pass them as strings (e.g., `"1"`, `"2"`).
212+
#[serde(skip_serializing_if = "Option::is_none")]
213+
pub ids: Option<Vec<&'a str>>,
205214
}
206215

207216
impl<'a, Http: HttpClient> DocumentsQuery<'a, Http> {
@@ -214,6 +223,7 @@ impl<'a, Http: HttpClient> DocumentsQuery<'a, Http> {
214223
fields: None,
215224
sort: None,
216225
filter: None,
226+
ids: None,
217227
}
218228
}
219229

@@ -314,6 +324,29 @@ impl<'a, Http: HttpClient> DocumentsQuery<'a, Http> {
314324
self
315325
}
316326

327+
/// Specify a list of document IDs to retrieve.
328+
///
329+
/// # Example
330+
///
331+
/// ```
332+
/// # use meilisearch_sdk::{client::*, indexes::*, documents::*};
333+
/// # use serde::{Deserialize, Serialize};
334+
/// #
335+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
336+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
337+
/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
338+
/// let index = client.index("get_documents_by_ids_example");
339+
/// let mut query = DocumentsQuery::new(&index);
340+
/// query.with_ids(["1", "2"]);
341+
/// ```
342+
pub fn with_ids(
343+
&mut self,
344+
ids: impl IntoIterator<Item = &'a str>,
345+
) -> &mut DocumentsQuery<'a, Http> {
346+
self.ids = Some(ids.into_iter().collect());
347+
self
348+
}
349+
317350
/// Execute the get documents query.
318351
///
319352
/// # Example
@@ -468,6 +501,19 @@ mod tests {
468501
Ok(())
469502
}
470503

504+
#[meilisearch_test]
505+
async fn test_get_documents_by_ids(client: Client, index: Index) -> Result<(), Error> {
506+
setup_test_index(&client, &index).await?;
507+
508+
let documents = DocumentsQuery::new(&index)
509+
.with_ids(["1", "3"]) // retrieve by IDs
510+
.execute::<MyObject>()
511+
.await?;
512+
513+
assert_eq!(documents.results.len(), 2);
514+
Ok(())
515+
}
516+
471517
#[meilisearch_test]
472518
async fn test_delete_documents_with(client: Client, index: Index) -> Result<(), Error> {
473519
setup_test_index(&client, &index).await?;

src/features.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ pub struct ExperimentalFeaturesResult {
1414
pub contains_filter: bool,
1515
pub network: bool,
1616
pub edit_documents_by_function: bool,
17+
#[serde(default)]
18+
pub multimodal: bool,
1719
}
1820

1921
/// Struct representing the experimental features request.
@@ -45,6 +47,8 @@ pub struct ExperimentalFeatures<'a, Http: HttpClient> {
4547
pub network: Option<bool>,
4648
#[serde(skip_serializing_if = "Option::is_none")]
4749
pub edit_documents_by_function: Option<bool>,
50+
#[serde(skip_serializing_if = "Option::is_none")]
51+
pub multimodal: Option<bool>,
4852
}
4953

5054
impl<'a, Http: HttpClient> ExperimentalFeatures<'a, Http> {
@@ -57,6 +61,7 @@ impl<'a, Http: HttpClient> ExperimentalFeatures<'a, Http> {
5761
network: None,
5862
contains_filter: None,
5963
edit_documents_by_function: None,
64+
multimodal: None,
6065
}
6166
}
6267

@@ -140,6 +145,11 @@ impl<'a, Http: HttpClient> ExperimentalFeatures<'a, Http> {
140145
self.network = Some(network);
141146
self
142147
}
148+
149+
pub fn set_multimodal(&mut self, multimodal: bool) -> &mut Self {
150+
self.multimodal = Some(multimodal);
151+
self
152+
}
143153
}
144154

145155
#[cfg(test)]
@@ -155,6 +165,7 @@ mod tests {
155165
features.set_contains_filter(true);
156166
features.set_network(true);
157167
features.set_edit_documents_by_function(true);
168+
features.set_multimodal(true);
158169
let _ = features.update().await.unwrap();
159170

160171
let res = features.get().await.unwrap();
@@ -163,5 +174,6 @@ mod tests {
163174
assert!(res.contains_filter);
164175
assert!(res.network);
165176
assert!(res.edit_documents_by_function);
177+
assert!(res.multimodal);
166178
}
167179
}

src/indexes.rs

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ impl<Http: HttpClient> Index<Http> {
517517
&self,
518518
documents_query: &DocumentsQuery<'_, Http>,
519519
) -> Result<DocumentsResults<T>, Error> {
520-
if documents_query.filter.is_some() {
520+
if documents_query.filter.is_some() || documents_query.ids.is_some() {
521521
let url = format!("{}/indexes/{}/documents/fetch", self.client.host, self.uid);
522522
return self
523523
.client
@@ -1325,6 +1325,55 @@ impl<Http: HttpClient> Index<Http> {
13251325
Ok(self.primary_key.as_deref())
13261326
}
13271327

1328+
/// Compact this index to reduce disk usage.
1329+
///
1330+
/// Triggers a compaction task for the current index. Once completed, the
1331+
/// index data is compacted on disk.
1332+
///
1333+
/// # Example
1334+
///
1335+
/// ```
1336+
/// # use meilisearch_sdk::{client::*, indexes::*, tasks::Task};
1337+
/// # let MEILISEARCH_URL = option_env!("MEILISEARCH_URL").unwrap_or("http://localhost:7700");
1338+
/// # let MEILISEARCH_API_KEY = option_env!("MEILISEARCH_API_KEY").unwrap_or("masterKey");
1339+
/// # tokio::runtime::Builder::new_current_thread().enable_all().build().unwrap().block_on(async {
1340+
/// # let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
1341+
/// # let index = client
1342+
/// # .create_index("compact_example", None)
1343+
/// # .await
1344+
/// # .unwrap()
1345+
/// # .wait_for_completion(&client, None, None)
1346+
/// # .await
1347+
/// # .unwrap()
1348+
/// # .try_make_index(&client)
1349+
/// # .unwrap();
1350+
///
1351+
/// let task = index
1352+
/// .compact()
1353+
/// .await
1354+
/// .unwrap()
1355+
/// .wait_for_completion(&client, None, None)
1356+
/// .await
1357+
/// .unwrap();
1358+
///
1359+
/// assert!(matches!(task, Task::Succeeded { .. }));
1360+
/// # index.delete().await.unwrap().wait_for_completion(&client, None, None).await.unwrap();
1361+
/// # });
1362+
/// ```
1363+
pub async fn compact(&self) -> Result<TaskInfo, Error> {
1364+
self.client
1365+
.http_client
1366+
.request::<(), (), TaskInfo>(
1367+
&format!("{}/indexes/{}/compact", self.client.host, self.uid),
1368+
Method::Post {
1369+
query: (),
1370+
body: (),
1371+
},
1372+
202,
1373+
)
1374+
.await
1375+
}
1376+
13281377
/// Get a [Task] from a specific [Index] to keep track of [asynchronous operations](https://www.meilisearch.com/docs/learn/advanced/asynchronous_operations).
13291378
///
13301379
/// # Example
@@ -2441,4 +2490,16 @@ mod tests {
24412490
}
24422491
Ok(())
24432492
}
2493+
2494+
#[meilisearch_test]
2495+
async fn test_compact_index_succeeds(client: Client, index: Index) -> Result<(), Error> {
2496+
let task = index
2497+
.compact()
2498+
.await?
2499+
.wait_for_completion(&client, None, None)
2500+
.await?;
2501+
2502+
assert!(task.is_success());
2503+
Ok(())
2504+
}
24442505
}

0 commit comments

Comments
 (0)