1个稳定版本
7.14.0 | 2023年1月14日 |
---|
#2859 在 数据库接口
用于 elastic_lens
2KB
Elastic Lens
一个用于处理Elasticsearch的具有观点的框架。
关于
一个简单的DSL框架,用于构建Elasticsearch请求以及解析响应。几乎可以肯定不是所有功能都可用,请阅读文档并确保它适合您的需求。
该项目尚处于初期阶段,目前支持一个实际工作项目。这是目前推动其发展的原因;然而,如果您有任何建议或修改,请随时提出问题 👍。
入门
在您的 Cargo.toml
文件中
# You must pick one of the currently two supported adapters
# - "official_es7"
# - "official_es8"
elastic_lens = { version = "0.1.8", features = ["official_es7"] }
tokio = { version = "1", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
功能浏览
所有这些示例也可以在 examples/sample_code.rs
中找到。
创建客户端
use elastic_lens::{
client::{Client, DefaultAdapter},
Error,
};
pub fn create_client() -> Result<Client<DefaultAdapter>, Error> {
Ok(Client::default_builder()
.host("http://localhost:9200")
.index("sample-index")
.credentials("username", "secret")
.default_limit(20)
.build()?)
}
简单搜索
// See `examples/inventory_item.rs` for definition
use super::inventory_item::*;
use elastic_lens::{prelude::*, response::SearchResults, Error};
pub async fn clothing_inventory() -> Result<SearchResults<InventoryItem>, Error> {
let client = create_client()?;
let mut search = Search::default();
search.with(CATEGORY.contains("clothing"));
search.with(COST.greater_than(500));
Ok(client.search(&search).await?)
}
复杂搜索
use elastic_lens::{prelude::*, request::search::GeoPoint, response::SearchResults, Error};
use serde_json::Value;
// Getting the documents back as serde JSON
// The client will deserialize the `_source` to any type
// that implements for it. See `examples/inventory_item.rs`
// for an example.
pub async fn complex_search() -> Result<SearchResults<Value>, Error> {
let client = create_client()?;
let mut search = Search::default();
search.with(
field("server.location")
.within(500)
.miles()
.of(GeoPoint::new(12.2, 18.9)),
);
search.with(field("log.level").has_any_of(["error", "warning"]));
search.with(field("log.trace").exists());
search.with(if_any_match(|any| {
any.with(field("service").contains("backend-core"));
any.with(if_all_match(|all| {
all.with(field("service").contains("frontend-core"));
all.with(field("tags").has_any_of(["market-place", "registration"]));
}));
}));
Ok(client.search(&search).await?)
}
多搜索
use super::inventory_item::*;
use elastic_lens::{prelude::*, Error};
pub async fn report_clothing_and_office() -> Result<(), Error> {
let client = create_client()?;
let mut clothing = Search::default();
clothing.with(CATEGORY.contains("clothing"));
let mut office = Search::default();
office.with(CATEGORY.contains("office"));
let results = client
.multi_search::<InventoryItem>(&[clothing, office])
.await?;
println!("Clothing:");
for doc in results[0].docs() {
println!("{doc:?}");
}
println!("\nOffice:");
for doc in results[1].docs() {
println!("{doc:?}");
}
Ok(())
}
简单字段排序
use elastic_lens::{prelude::*, response::SearchResults, Error};
use serde_json::Value;
pub async fn five_cheapest_items() -> Result<SearchResults<Value>, Error> {
let client = create_client()?;
let mut search = Search::default();
search.sort(by_field("cost").ascending().with_missing_values_last());
search.set_limit(5);
Ok(client.search(&search).await?)
}
按地理距离排序
use elastic_lens::{prelude::*, request::search::GeoPoint, response::SearchResults, Error};
use serde_json::Value;
pub async fn nearest_allies() -> Result<SearchResults<Value>, Error> {
let client = create_client()?;
let mut search = Search::default();
search.with(field("user.is_ally").contains(true));
search.sort(
by_field("user.location")
.by_distance_from(GeoPoint::new(1.1, 2.2))
.in_ascending_order()
.ignore_unmapped_documents(),
);
Ok(client.search(&search).await?)
}
脚本得分排序
use super::inventory_item::*;
use elastic_lens::{prelude::*, response::SearchResults, Error};
pub async fn some_cheaper_first() -> Result<SearchResults<InventoryItem>, Error> {
let client = create_client()?;
let mut search = Search::default();
search.with(!SUB_CATEGORY.contains("beanie"));
search.sort(
by_script(
r#"
if ( doc['cost'].value > params.breakpoint ) {
doc['cost'].value / 100
} else {
doc['cost'].value * 100
}
"#,
)
.with_params([("breakpoint", 1300)]),
);
Ok(client.search(&search).await?)
}
术语聚合
use elastic_lens::{prelude::*, Error};
use serde_json::Value;
pub async fn category_aggs_with_sub_categories() -> Result<StringTerms, Error> {
let client = create_client()?;
let mut search = Search::default();
search
.create_aggregation("categories")
.for_field("category")
.count_terms()
.with_sub_aggregations(|sub| {
sub.create_aggregation("sub-categories")
.for_field("sub_category")
.count_terms()
.for_top(20);
});
let mut results = client.search::<Value>(&search).await?;
Ok(results.aggs_mut().take("categories")?)
}
统计聚合
use elastic_lens::{prelude::*, Error};
use serde_json::Value;
pub async fn collect_price_stats() -> Result<Stats, Error> {
let client = create_client()?;
let mut search = Search::default();
search
.create_aggregation("price-stats")
.for_field("item.price")
.collect_stats();
let mut results = client.search::<Value>(&search).await?;
Ok(results.aggs_mut().take("price-stats")?)
}
过滤器聚合
use super::inventory_item::*;
use elastic_lens::{prelude::*, Error};
pub async fn less_than_20_report() -> Result<Filtered, Error> {
let client = create_client()?;
let mut search = Search::default();
search
.create_aggregation("under-twenty")
.filtered_by(|search| search.with(COST.less_than(20_00)))
.with_sub_aggregations(|aggs| {
aggs.create_aggregation("categories")
.for_field("category")
.count_terms()
.for_top(20);
});
// we don't care about documents
search.set_limit(0);
// since we know we won't have any results we can use `()`
// as the type since it doesn't matter
let mut results = client.search::<()>(&search).await?;
Ok(results.aggs_mut().take::<Filtered>("under-twenty")?)
}
与示例玩耍
您需要在端口9200上运行Elasticsearch。您可以使用以下命令将其容器化运行:
docker run -it -p 9200:9200 -e "discovery.type=single-node" elasticsearch:7.11.2
然后,运行 bin/setup_index.sh
来引导一些示例将查询的数据。
示例位于 examples/
目录中,可以使用 cargo 运行: cargo run --example <name> (..args..)
这里是当前的示例列表
fetch_a_document
simple_search
simple_aggs
filter_aggs
multi_search
simple_sort
lib.rs
:
这个crate用作跟踪官方Elasticsearch 7.x.x系列客户端的简单方法。除非您使用 ElasticLens
,否则没有理由使用这个crate。
依赖项
~7–21MB
~324K SLoC