Rust搜索引擎库meilisearch-sdk的使用:快速集成全文搜索功能到Rust应用
Rust搜索引擎库meilisearch-sdk的使用:快速集成全文搜索功能到Rust应用
Meilisearch Rust SDK是Rust开发者使用的Meilisearch API客户端。Meilisearch是一个开源搜索引擎。
安装
在您的Cargo.toml
中添加以下内容:
[dependencies]
meilisearch-sdk = "0.29.1"
可选依赖项:
futures = "0.3" # 如果您不使用异步运行时,可以阻塞异步函数
serde = { version = "1.0", features = ["derive"] }
快速入门
添加文档
use meilisearch_sdk::client::*;
use serde::{Serialize, Deserialize};
use futures::executor::block_on;
#[derive(Serialize, Deserialize, Debug)]
struct Movie {
id: usize,
title: String,
genres: Vec<String>,
}
#[tokio::main(flavor = "current_thread")]
async fn main() {
// 创建一个客户端(不发送任何请求,所以不会失败)
let client = Client::new(MEILISEARCH_URL, Some(MEILISEARCH_API_KEY)).unwrap();
// 索引是存储文档的地方
let movies = client.index("movies");
// 在索引中添加一些电影。如果索引'movies'不存在,Meilisearch会在第一次添加文档时创建它
movies.add_documents(&[
Movie { id: 1, title: String::from("Carol"), genres: vec!["Romance".to_string(), "Drama".to_string()] },
Movie { id: 2, title: String::from("Wonder Woman"), genres: vec!["Action".to_string(), "Adventure".to_string()] },
Movie { id: 3, title: String::from("Life of Pi"), genres: vec!["Adventure".to_string(), "Drama".to_string()] },
Movie { id: 4, title: String::from("Mad Max"), genres: vec!["Adventure".to_string(), "Science Fiction".to_string()] },
Movie { id: 5, title: String::from("Moana"), genres: vec!["Fantasy".to_string(), "Action".to_string()] },
Movie { id: 6, title: String::from("Philadelphia"), genres: vec!["Drama".to_string()] },
], Some("id")).await.unwrap();
}
基本搜索
// Meilisearch具有容错能力:
println!("{:?}", client.index("movies_2").search().with_query("caorl").execute::<Movie>().await.unwrap().hits);
输出:
[Movie { id: 1, title: String::from("Carol"), genres: vec!["Romance", "Drama"] }]
自定义搜索
let search_result = client.index("movies_3")
.search()
.with_query("phil")
.with_attributes_to_highlight(Selectors::Some(&["*"]))
.execute::<Movie>()
.await
.unwrap();
println!("{:?}", search_result.hits);
带过滤器的自定义搜索
如果要启用过滤,必须将您的属性添加到filterableAttributes
索引设置中。
let filterable_attributes = [
"id",
"genres",
];
client.index("movies_4").set_filterable_attributes(&filterable_attributes).await.unwrap();
然后,您可以执行搜索:
let search_result = client.index("movies_5")
.search()
.with_query("wonder")
.with_filter("id > 1 AND genres = Action")
.execute::<Movie>()
.await
.unwrap();
println!("{:?}", search_result.hits);
完整示例
use meilisearch_sdk::client::*;
use serde::{Serialize, Deserialize};
use tokio;
#[derive(Serialize, Deserialize, Debug)]
struct Movie {
id: usize,
title: String,
genres: Vec<String>,
}
#[tokio::main]
async fn main() {
// 初始化客户端
let client = Client::new("http://localhost:7700", Some("masterKey")).unwrap();
// 获取或创建索引
let movies = client.index("movies");
// 添加文档
movies.add_documents(&[
Movie { id: 1, title: "Carol".to_string(), genres: vec!["Romance".to_string(), "Drama".to_string()] },
Movie { id: 2, title: "Wonder Woman".to_string(), genres: vec!["Action".to_string(), "Adventure".to_string()] },
Movie { id: 3, title: "Life of Pi".to_string(), genres: vec!["Adventure".to_string(), "Drama".to_string()] },
], Some("id")).await.unwrap();
// 简单搜索
let result = movies.search()
.with_query("wonder")
.execute::<Movie>()
.await
.unwrap();
println!("搜索结果: {:?}", result.hits);
// 设置可过滤属性
movies.set_filterable_attributes(&["genres"]).await.unwrap();
// 带过滤器的搜索
let filtered_result = movies.search()
.with_query("woman")
.with_filter("genres = Action")
.execute::<Movie>()
.await
.unwrap();
println!("过滤后的结果: {:?}", filtered_result.hits);
}
这个示例展示了如何:
- 初始化Meilisearch客户端
- 创建/获取索引
- 添加文档到索引
- 执行基本搜索
- 设置可过滤属性
- 执行带过滤器的搜索
您可以根据需要调整搜索参数和过滤器条件来满足您的应用需求。
1 回复
meilisearch-sdk使用指南:快速集成全文搜索功能到Rust应用
介绍
meilisearch-sdk是一个Rust客户端库,用于与MeiliSearch搜索引擎交互。MeiliSearch是一个开源的、超快速的搜索引擎,可以轻松地为你的应用添加强大的搜索功能。
主要特性
- 简单易用的API
- 即时搜索(输入时实时显示结果)
- 高度可定制(相关性排序、过滤、分面等)
- 支持多种数据类型
- 轻量级且快速
安装
在Cargo.toml中添加依赖:
[dependencies]
meilisearch-sdk = "0.20"
tokio = { version = "1.0", features = ["full"] }
基本使用方法
1. 连接到MeiliSearch服务器
use meilisearch_sdk::{client::*, indexes::*};
#[tokio::main]
async fn main() {
// 连接到本地MeiliSearch实例
let client = Client::new("http://localhost:7700", "masterKey");
// 检查服务器健康状态
if let Ok(health) = client.health().await {
println!("Server is healthy: {:?}", health);
}
}
2. 创建索引并添加文档
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct Movie {
id: String,
title: String,
genres: Vec<String>,
year: i32,
}
async fn create_index(client: &Client) {
// 创建或获取索引
let movies = client.index("movies");
// 定义文档
let documents = vec![
Movie {
id: "1".to_string(),
title: "The Shawshank Redemption".to_string(),
genres: vec!["Drama".to_string(), "Crime".to_string()],
year: 1994,
},
Movie {
id: "2".to_string(),
title: "The Godfather".to_string(),
genres: vec!["Crime".to_string(), "Drama"].to_string()],
year: 1972,
},
];
// 添加文档到索引
let task = movies.add_documents(&documents, Some("id")).await;
match task {
Ok(task) => println!("Documents added successfully: {:?}", task),
Err(e) => eprintln!("Error adding documents: {}", e),
}
}
3. 执行搜索
async fn search_movies(client: &Client) {
let movies = client.index("movies");
// 简单搜索
let results = movies.search()
.with_query("shawshank")
.execute::<Movie>()
.await
.unwrap();
println!("Search results for 'shawshank':");
for hit in results.hits {
println!("- {} ({})", hit.result.title, hit.result.year);
}
// 带过滤的搜索
let filtered_results = movies.search()
.with_query("crime")
.with_filter("year > 1990")
.execute::<Movie>()
.await
.unwrap();
println!("\nFiltered results (crime movies after 1990):");
for hit in filtered_results.hits {
println!("- {} ({})", hit.result.title, hit.result.year);
}
}
高级功能
1. 配置索引设置
async fn configure_index(client: &Client) {
let movies = client.index("movies");
// 设置搜索属性
let settings = Settings::new()
.with_searchable_attributes(["title", "genres"])
.with_filterable_attributes(["year", "genres"]);
movies.set_settings(&settings).await.unwrap();
}
2. 同义词和停用词
async fn configure_synonyms(client: &Client) {
let movies = client.index("movies");
// 设置同义词
let synonyms = json!({
"flick": ["movie", "film"],
"movie": ["flick", "film"],
"film": ["flick", "movie"]
});
movies.set_synonyms(&synonyms).await.unwrap();
}
3. 分面搜索
async fn facet_search(client: &Client) {
let movies = client.index("movies");
// 获取所有流派的分面统计
let results = movies.search()
.with_query("")
.with_facets(["genres"])
.execute::<Movie>()
.await
.unwrap();
if let Some(facets) = results.facet_distribution {
if let Some(genres) = facets.get("genres") {
println!("Genre distribution:");
for (genre, count) in genres {
println!("- {}: {}", genre, count);
}
}
}
}
完整示例代码
use meilisearch_sdk::{client::*, indexes::*, settings::Settings};
use serde_json::json;
#[derive(Debug, serde::Serialize, serde::Deserialize)]
struct Movie {
id: String,
title: String,
genres: Vec<String>,
year: i32,
}
#[tokio::main]
async fn main() {
// 1. 连接到服务器
let client = Client::new("http://localhost:7700", "masterKey");
// 2. 创建索引并添加文档
let movies = client.index("movies");
let documents = vec![
Movie {
id: "1".to_string(),
title: "The Shawshank Redemption".to_string(),
genres: vec!["Drama".to_string(), "Crime".to_string()],
year: 1994,
},
Movie {
id: "2".to_string(),
title: "The Godfather".to_string(),
genres: vec!["Crime".to_string(), "Drama".to_string()],
year: 1972,
},
];
movies.add_documents(&documents, Some("id")).await.unwrap();
// 3. 配置索引
let settings = Settings::new()
.with_searchable_attributes(["title", "genres"])
.with_filterable_attributes(["year", "genres"]);
movies.set_settings(&settings).await.unwrap();
// 4. 执行搜索
let results = movies.search()
.with_query("shawshank")
.execute::<Movie>()
.await
.unwrap();
println!("Search results:");
for hit in results.hits {
println!("- {} ({})", hit.result.title, hit.result.year);
}
// 5. 分面搜索
let facet_results = movies.search()
.with_query("")
.with_facets(["genres"])
.execute::<Movie>()
.await
.unwrap();
if let Some(facets) = facet_results.facet_distribution {
if let Some(genres) = facets.get("genres") {
println!("\nGenre distribution:");
for (genre, count) in genres {
println!("- {}: {}", genre, count);
}
}
}
}
总结
meilisearch-sdk为Rust应用提供了简单高效的方式来集成MeiliSearch的强大搜索功能。通过这个库,你可以快速实现全文搜索、过滤、分面搜索等高级功能,同时保持代码的简洁性和高性能。