Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions examples/cli-app/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[package]
name = "cli-app"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
meilisearch-sdk = {path="../.."}
futures = "0.3"
serde = { version="1.0", features = ["derive"] }
serde_json = "1.0"
lazy_static = "1.4.0"
74 changes: 74 additions & 0 deletions examples/cli-app/assets/clothes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
[
{
"id": 1,
"seaon": "winter",
"article": "sweater",
"cost": 63.40,
"size":"L",
"pattern":"striped"
},
{
"id": 2,
"seaon": "spring",
"article": "sweat pants",
"cost": 18.00,
"size":"XXXL",
"pattern":"floral"
},
{
"id": 3,
"seaon": "fall",
"article": "t-shirt",
"cost": 1634.90,
"size":"M",
"pattern":"solid black"
},
{
"id": 4,
"seaon": "summer",
"article": "tank top",
"cost": 3.40,
"size":"L",
"pattern":"diagonal"
},
{
"id": 5,
"seaon": "winter",
"article": "jeans",
"cost": 4.20,
"size":"XL",
"pattern":"striped"
},
{
"id": 6,
"seaon": "spring",
"article": "sun dress",
"cost": 12634.56,
"size":"L",
"pattern":"floral"
},
{
"id": 7,
"seaon": "fall",
"article": "sweatshirt",
"cost": 90.80,
"size":"M",
"pattern":"checker"
},
{
"id": 8,
"seaon": "summer",
"article": "shorts",
"cost": 16.34,
"size":"XS",
"pattern":"solid beige"
},
{
"id": 9,
"seaon": "winter",
"article": "jacket",
"cost": 634,
"size":"L",
"pattern":"camo"
}
]
166 changes: 166 additions & 0 deletions examples/cli-app/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
use futures::executor::block_on;
use lazy_static::lazy_static;
use meilisearch_sdk::{client::*,settings::Settings};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::io::{stdin};

// instantiate the client. load it once
lazy_static! {
static ref CLIENT: Client = Client::new("http://localhost:7700", "masterKey");
}

fn main() {
block_on(async move {
// build the index
build_index().await;

// enter in search queries or quit
loop {
println!("Enter a search query or type \"q\" or \"quit\" to quit:");
let mut input_string = String::new();
stdin()
.read_line(&mut input_string)
.expect("Failed to read line");
match input_string.trim() {
"quit" | "q" | "" => {
println!("exiting...");
break;
}
_ => {
search(input_string.trim()).await;
}
}
}
// get rid of the index at the end, doing this only so users don't have the index without knowing
let _ = CLIENT.delete_index("clothes").await.unwrap();
})
}

async fn search(query: &str) {
// make the search query, which excutes and serializes hits into the
// ClothesDisplay struct
let query_results = CLIENT
.index("clothes")
.search()
.with_query(query)
.execute::<ClothesDisplay>()
.await
.unwrap()
.hits;

// display the query results
if query_results.is_empty() {
println!("no results...");
} else {
for clothes in query_results {
let display = clothes.result;
println!("{}", format_args!("{}", display));
}
}
}

async fn build_index() {
// reading and parsing the file
let content = include_str!("../assets/clothes.json");

// serialize the string to clothes objects
let clothes: Vec<Clothes> = serde_json::from_str(content).unwrap();

//create displayed attributes
let displayed_attributes = ["article", "cost", "size", "pattern"];

// Create ranking rules
let ranking_rules = ["words", "typo", "attribute", "exactness", "cost:asc"];

//create searchable attributes
let searchable_attributes = ["seaon", "article", "size", "pattern"];

// create the synonyms hashmap
let mut synonyms = std::collections::HashMap::new();
synonyms.insert(
"sweater",
vec!["cardigan", "long-sleeve"],
);
synonyms.insert("sweat pants", vec!["joggers", "gym pants"]);
synonyms.insert(
"t-shirt",
vec!["tees", "tshirt"],
);

//create the settings struct
let settings = Settings::new()
.with_ranking_rules(ranking_rules)
.with_searchable_attributes(searchable_attributes)
.with_displayed_attributes(displayed_attributes)
.with_synonyms(synonyms);

//add the settings to the index
let result = CLIENT
.index("clothes")
.set_settings(&settings)
.await
.unwrap()
.wait_for_completion(&CLIENT, None, None)
.await
.unwrap();

if result.is_failure() {
panic!(
"Encountered an error while setting settings for index: {:?}",
result.unwrap_failure()
);
}

// add the documents
let result = CLIENT
.index("clothes")
.add_or_update(&clothes, Some("id"))
.await
.unwrap()
.wait_for_completion(&CLIENT, None, None)
.await
.unwrap();

if result.is_failure() {
panic!(
"Encountered an error while sending the documents: {:?}",
result.unwrap_failure()
);
}
}

/// Base search object.
#[derive(Serialize, Deserialize, Debug)]
pub struct Clothes {
id: usize,
seaon: String,
article: String,
cost: f32,
size: String,
pattern: String,
}

/// Search results get serialized to this struct
#[derive(Serialize, Deserialize, Debug)]
pub struct ClothesDisplay {
article: String,
cost: f32,
size: String,
pattern: String,
}

impl fmt::Display for ClothesDisplay {
// This trait requires `fmt` with this exact signature.
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
// Write strictly the first element into the supplied output
// stream: `f`. Returns `fmt::Result` which indicates whether the
// operation succeeded or failed. Note that `write!` uses syntax which
// is very similar to `println!`.
write!(
f,
"result\n article: {},\n price: {},\n size: {},\n pattern: {}\n",
self.article, self.cost, self.size, self.pattern
)
}
}