Skip to content

Commit f941ae8

Browse files
bors[bot]ginglis13curquiza
authored
Merge #193
193: Add custom search with `filter` example r=curquiza a=ginglis13 #192 Add section to README with example for updating index facets and running filtered search against updated index. Tested with movies example locally. Co-authored-by: ginglis13 <[email protected]> Co-authored-by: Clémentine Urquizar <[email protected]>
2 parents ed2edbc + b5d9d59 commit f941ae8

File tree

2 files changed

+159
-2
lines changed

2 files changed

+159
-2
lines changed

README.md

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,51 @@ Output:
134134
[Movie{id: 1, title: String::from("Carol"), genres: vec!["Romance", "Drama"]}]
135135
```
136136

137-
## 🌐 Running in the Browser with WASM <!-- omit in TOC -->
137+
##### Custom Search With Filters <!-- omit in TOC -->
138+
139+
If you want to enable filtering, you must add your attributes to the `filterableAttributes`
140+
index setting.
141+
142+
```rust
143+
let filterable_attributes = [
144+
"id",
145+
"genres"
146+
];
147+
movies.set_filterable_attributes(&filterable_attributes).await.unwrap();
148+
```
149+
150+
You only need to perform this operation once.
151+
152+
Note that MeiliSearch will rebuild your index whenever you update `filterableAttributes`.
153+
Depending on the size of your dataset, this might take time. You can track the whole process
154+
using the [update
155+
status](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status).
156+
157+
Then, you can perform the search:
158+
159+
```rust
160+
println!("{:?}", movies.search().with_query("wonder").with_filter("id > 1 AND genres = Action")
161+
.execute::<Movie>().await.unwrap().hits);
162+
```
163+
164+
```json
165+
{
166+
"hits": [
167+
{
168+
"id": 2,
169+
"title": "Wonder Woman",
170+
"genres": ["Action", "Adventure"]
171+
}
172+
],
173+
"offset": 0,
174+
"limit": 20,
175+
"nbHits": 1,
176+
"processingTimeMs": 0,
177+
"query": "wonder"
178+
}
179+
```
180+
181+
### 🌐 Running in the Browser with WASM <!-- omit in TOC -->
138182

139183
This crate fully supports WASM.
140184

src/lib.rs

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,120 @@
8888
//! [Movie{id: 1, title: String::from("Carol"), genres: vec!["Romance", "Drama"]}]
8989
//! ```
9090
//!
91-
//! # 🌐 Running in the Browser with WASM <!-- omit in TOC -->
91+
//! #### Custom Search With Filters <!-- omit in TOC -->
92+
//!
93+
//! If you want to enable filtering, you must add your attributes to the `filterableAttributes`
94+
//! index setting.
95+
//!
96+
//! ```
97+
//! # use meilisearch_sdk::{document::*, client::*, search::*};
98+
//! # use serde::{Serialize, Deserialize};
99+
//! # use futures::executor::block_on;
100+
//! # #[derive(Serialize, Deserialize, Debug)]
101+
//! # struct Movie {
102+
//! # id: usize,
103+
//! # title: String,
104+
//! # genres: Vec<String>,
105+
//! # }
106+
//! # // That trait is required to make a struct usable by an index
107+
//! # impl Document for Movie {
108+
//! # type UIDType = usize;
109+
//! # fn get_uid(&self) -> &Self::UIDType {
110+
//! # &self.id
111+
//! # }
112+
//! # }
113+
//! # fn main() { block_on(async move {
114+
//! # // Create a client (without sending any request so that can't fail)
115+
//! # let client = Client::new("http://localhost:7700", "masterKey");
116+
//! # // Get the index called "movies"
117+
//! # let movies = client.get_or_create("movies").await.unwrap();
118+
//! let filterable_attributes = [
119+
//! "id",
120+
//! "genres"
121+
//! ];
122+
//! movies.set_filterable_attributes(&filterable_attributes).await.unwrap();
123+
//! # // Add some movies in the index
124+
//! # movies.add_documents(&[
125+
//! # Movie{id: 1, title: String::from("Carol"), genres: vec!["Romance".to_string(), "Drama".to_string()]},
126+
//! # Movie{id: 2, title: String::from("Wonder Woman"), genres: vec!["Action".to_string(), "Adventure".to_string()]},
127+
//! # Movie{id: 3, title: String::from("Life of Pi"), genres: vec!["Adventure".to_string(), "Drama".to_string()]},
128+
//! # Movie{id: 4, title: String::from("Mad Max"), genres: vec!["Adventure".to_string(), "Science Fiction".to_string()]},
129+
//! # Movie{id: 5, title: String::from("Moana"), genres: vec!["Fantasy".to_string(), "Action".to_string()]},
130+
//! # Movie{id: 6, title: String::from("Philadelphia"), genres: vec!["Drama".to_string()]},
131+
//! # ], Some("id")).await.unwrap();
132+
//! # // Query movies (note that there is a typo)
133+
//! # println!("{:?}", movies.search().with_query("carol").execute::<Movie>().await.unwrap().hits);
134+
//! # })}
135+
//! ```
136+
//!
137+
//! You only need to perform this operation once.
138+
//!
139+
//! Note that MeiliSearch will rebuild your index whenever you update `filterableAttributes`.
140+
//! Depending on the size of your dataset, this might take time. You can track the whole process
141+
//! using the [update
142+
//! status](https://docs.meilisearch.com/reference/api/updates.html#get-an-update-status).
143+
//!
144+
//! Then, you can perform the search:
145+
//!
146+
//! ```
147+
//! # use meilisearch_sdk::{document::*, client::*, search::*};
148+
//! # use serde::{Serialize, Deserialize};
149+
//! # use futures::executor::block_on;
150+
//! # #[derive(Serialize, Deserialize, Debug)]
151+
//! # struct Movie {
152+
//! # id: usize,
153+
//! # title: String,
154+
//! # genres: Vec<String>,
155+
//! # }
156+
//! # // That trait is required to make a struct usable by an index
157+
//! # impl Document for Movie {
158+
//! # type UIDType = usize;
159+
//! # fn get_uid(&self) -> &Self::UIDType {
160+
//! # &self.id
161+
//! # }
162+
//! # }
163+
//! # fn main() { block_on(async move {
164+
//! # // Create a client (without sending any request so that can't fail)
165+
//! # let client = Client::new("http://localhost:7700", "masterKey");
166+
//! # // Get the index called "movies"
167+
//! # let movies = client.get_or_create("movies").await.unwrap();
168+
//! # let filterable_attributes = [
169+
//! # "id",
170+
//! # "genres"
171+
//! # ];
172+
//! # movies.set_filterable_attributes(&filterable_attributes).await.unwrap();
173+
//! # // Add some movies in the index
174+
//! # movies.add_documents(&[
175+
//! # Movie{id: 1, title: String::from("Carol"), genres: vec!["Romance".to_string(), "Drama".to_string()]},
176+
//! # Movie{id: 2, title: String::from("Wonder Woman"), genres: vec!["Action".to_string(), "Adventure".to_string()]},
177+
//! # Movie{id: 3, title: String::from("Life of Pi"), genres: vec!["Adventure".to_string(), "Drama".to_string()]},
178+
//! # Movie{id: 4, title: String::from("Mad Max"), genres: vec!["Adventure".to_string(), "Science Fiction".to_string()]},
179+
//! # Movie{id: 5, title: String::from("Moana"), genres: vec!["Fantasy".to_string(), "Action".to_string()]},
180+
//! # Movie{id: 6, title: String::from("Philadelphia"), genres: vec!["Drama".to_string()]},
181+
//! # ], Some("id")).await.unwrap();
182+
//! println!("{:?}", movies.search().with_query("wonder").with_filter("id > 1 AND genres = Action")
183+
//! .execute::<Movie>().await.unwrap().hits);
184+
//! # })}
185+
//! ```
186+
//!
187+
//! ```json
188+
//! {
189+
//! "hits": [
190+
//! {
191+
//! "id": 2,
192+
//! "title": "Wonder Woman",
193+
//! "genres": ["Action", "Adventure"]
194+
//! }
195+
//! ],
196+
//! "offset": 0,
197+
//! "limit": 20,
198+
//! "nbHits": 1,
199+
//! "processingTimeMs": 0,
200+
//! "query": "wonder"
201+
//! }
202+
//! ```
203+
//!
204+
//! ## 🌐 Running in the Browser with WASM <!-- omit in TOC -->
92205
//!
93206
//! This crate fully supports WASM.
94207
//!

0 commit comments

Comments
 (0)