发表于 2024/04/01 19:41:17 [rust] 浏览次数:323
1.依赖
serde = { version = "1.0.190", optional = true, features=["derive"]}
json = {version="0.12.4", optional=true}
serde_json = {version="1.0.108", optional=true}
elasticsearch = {version = "7.17.7-alpha.1", optional=true}
2.封装接口
//! @Date: Create in 2024-03-28 11:47:26
//! @Description:
//!
//!
use std::{collections::HashMap, fmt::Display};
use elasticsearch::{
http::transport::{SingleNodeConnectionPool, Transport, TransportBuilder},
indices::{IndicesCreateParts, IndicesDeleteParts},
params::Conflicts,
Elasticsearch,
};
use json::{number::Number, object::Object, JsonValue};
use reqwest::Url;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
#[derive(Debug)]
pub struct EsError {
pub msg: String,
}
impl std::fmt::Display for EsError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.msg)
}
}
// 自定义结果
pub type EsResult<T> = std::result::Result<T, EsError>;
//转换结果
fn check_result<T, E: Display>(result: Result<T, E>) -> EsResult<T> {
return match result {
Ok(r) => Result::Ok(r),
Err(err) => Result::Err(EsError {
msg: err.to_string(),
}),
};
}
// es字段类型
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct EsFieldType {
pub type_name: String, //类型名 text, keyword, byte,boolean, short,integer,long,float, half_float, scaled_float,double,date,dense_vector(向量)
pub store: bool, //是否存储
pub index: bool, //是否索引
pub dims: u16, //向量类型 需要指定向量维度
}
//转json字符串
impl Into<JsonValue> for EsFieldType {
fn into(self) -> JsonValue {
let mut obj: Object = Object::new();
//是否向量
let is_vec = self.type_name.as_str() == "dense_vector";
let is_text = self.type_name.as_str() == "text";
obj.insert("type", JsonValue::String(self.type_name));
obj.insert("store", JsonValue::Boolean(self.store));
obj.insert("index", JsonValue::Boolean(self.index));
if is_vec {
//向量类型
obj.insert("dims", JsonValue::Number(Number::from(self.dims))); //向量维度
}
if is_text {
obj.insert("analyzer", JsonValue::String("html_text_analyzer".into())); //使用自定义的分词器 忽略html标签
obj.insert("search_analyzer", JsonValue::String("ik_smart".into()));
}
json::JsonValue::Object(obj)
}
}
//es字段
#[derive(Debug, Serialize, Deserialize)]
pub struct EsField {
pub name: String, //字段名
pub filed_type: EsFieldType, //字段类型
}
//////////////////////////// 自定义查询对象,es查询的body是json格式,所以查询对象都要实现Into<JsonValu>这个trait//////////////////////////////////////////////////
/// 查询类型 枚举
#[derive(Clone, Debug, Serialize, PartialEq)]
pub enum QueryType {
Term,
Terms, //in查询 , bool_query.must.push(FieldQuery{query_type: QueryType::Terms,field_name: "_id".into(), field_value: Some(vec!["a0fdffd23a4c48a24caf0e6fe660f90b".to_string(), "ee5025966e7237720df1b47035e62c66".to_string()].into())});
Match, //match查询属于全文查询,在查询时,ES会先分析查询字符串,然后根据分词构建查询,满足其中一个分词就算
MatchPhrase, //在查询时也会先分析查询字符串,然后对这些词项进行搜索,不同的是match_phrase查询只会保留包含全部查询字符串的文档
Exists, //存在某个字段(且不能为null)
Range, //范围查询 gte lte
Vector, //向量查询(相似度)
Bool, //bool查询
}
///范围查询时,查询参数
#[derive(Clone, Debug)]
pub struct RangeValue {
pub gte: Option<Number>,
pub lte: Option<Number>,
}
impl Into<JsonValue> for RangeValue {
fn into(self) -> JsonValue {
let mut obj: Object = Object::new();
if let Some(g) = self.gte {
obj.insert("gte", g.into());
}
if let Some(l) = self.lte {
obj.insert("lte", l.into());
}
json::JsonValue::Object(obj)
}
}
///指定某个字段查询
#[derive(Clone, Debug)]
pub struct FieldQuery {
pub query_type: QueryType, //查询类型
pub field_name: String, //字段名
pub field_value: Option<JsonValue>, //查询参数
pub bool: Option<Box<BoolQuery>>, // 嵌套bool查询
}
impl FieldQuery {
//新建一个字段查询
pub fn new(query_type: QueryType, field_name: String, field_value: Option<JsonValue>) -> Self {
FieldQuery {
query_type, //查询类型
field_name, //字段名
field_value, //查询参数
bool: None,
}
}
//新建一个嵌套bool查询
pub fn new_bool(bool_query: BoolQuery) -> Self {
FieldQuery {
query_type: QueryType::Bool, //查询类型
field_name: "".into(), //字段名
field_value: None, //查询参数
bool: Some(Box::new(bool_query)),
}
}
}
//转json
impl Into<JsonValue> for FieldQuery {
fn into(self) -> JsonValue {
if let QueryType::Term = self.query_type {
return create_term_obj(self);
}
if QueryType::Match.eq(&self.query_type) {
return create_match_obj(self);
}
if QueryType::MatchPhrase.eq(&self.query_type) {
return create_match_phrase_obj(self);
}
if QueryType::Exists.eq(&self.query_type) {
return create_exists_obj(self);
}
if QueryType::Terms.eq(&self.query_type) {
return create_terms_obj(self);
}
if QueryType::Range.eq(&self.query_type) {
return create_range_obj(self);
}
if QueryType::Vector.eq(&self.query_type) {
return create_vec_obj(self);
}
if QueryType::Bool.eq(&self.query_type) {
if let Some(b) = self.bool {
return create_bool_obj(*b);
}
}
return json::JsonValue::Object(Object::new());
}
}
fn create_term_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
//term查询
let mut term_obj: Object = Object::new();
term_obj.insert(
&field_query.field_name,
JsonValue::from(field_query.field_value),
);
obj.insert("term", JsonValue::Object(term_obj));
return json::JsonValue::Object(obj);
}
fn create_match_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
//match
let mut value_obj = Object::new();
value_obj.insert("query", JsonValue::from(field_query.field_value));
value_obj.insert("analyzer", JsonValue::String("ik_smart".into()));
let mut field_obj = Object::new();
field_obj.insert(&field_query.field_name, JsonValue::Object(value_obj));
obj.insert("match", JsonValue::Object(field_obj));
return json::JsonValue::Object(obj);
}
fn create_match_phrase_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
//match
let mut value_obj = Object::new();
value_obj.insert("query", JsonValue::from(field_query.field_value));
value_obj.insert("analyzer", JsonValue::String("ik_smart".into()));
value_obj.insert("slop", JsonValue::Number(Number::from(20))); //指定slop大小(短语分词之间最大间隙)
let mut field_obj = Object::new();
field_obj.insert(&field_query.field_name, JsonValue::Object(value_obj));
obj.insert("match_phrase", JsonValue::Object(field_obj));
return json::JsonValue::Object(obj);
}
fn create_exists_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
let mut field_obj = Object::new();
field_obj.insert("field", field_query.field_name.into());
obj.insert("exists", JsonValue::Object(field_obj));
return json::JsonValue::Object(obj);
}
fn create_terms_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
let mut field_obj = Object::new();
field_obj.insert(&field_query.field_name, field_query.field_value.into());
obj.insert("terms", JsonValue::Object(field_obj));
return json::JsonValue::Object(obj);
}
//范围查询
fn create_range_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
let mut field_obj = Object::new();
field_obj.insert(&field_query.field_name, field_query.field_value.into());
obj.insert("range", JsonValue::Object(field_obj));
return json::JsonValue::Object(obj);
}
//向量查询
fn create_vec_obj(field_query: FieldQuery) -> JsonValue {
let mut obj: Object = Object::new();
let mut script_score_obj = Object::new();
let mut match_all_obj = Object::new();
match_all_obj.insert("match_all", Object::new().into());
script_score_obj.insert("query", match_all_obj.into());
let mut script_obj = Object::new();
script_obj.insert(
"source",
format!(
"cosineSimilarity(params.query_vector, '{}') + 1.0",
field_query.field_name
)
.into(),
);
let mut query_vec_obj = Object::new();
query_vec_obj.insert("query_vector", field_query.field_value.into());
script_obj.insert("params", query_vec_obj.into());
script_score_obj.insert("script", script_obj.into());
obj.insert("script_score", script_score_obj.into());
return json::JsonValue::Object(obj);
}
//嵌套bool
fn create_bool_obj(bool_query: BoolQuery) -> JsonValue {
let mut obj: Object = Object::new();
obj.insert("bool", bool_query.into());
json::JsonValue::Object(obj)
}
//bool查询
#[derive(Clone, Debug)]
pub struct BoolQuery {
pub must: Vec<FieldQuery>,
pub must_not: Vec<FieldQuery>,
pub should: Vec<FieldQuery>,
pub filter: Vec<FieldQuery>, //过滤
pub minimum_should_match: u8, //指定返回的文档必须匹配的should 子句的数量或百分比
}
impl BoolQuery {
pub fn new() -> Self {
BoolQuery {
must: vec![],
must_not: vec![],
should: vec![],
filter: vec![],
minimum_should_match: 1_u8,
}
}
pub fn new_query(
must: Vec<FieldQuery>,
must_not: Vec<FieldQuery>,
should: Vec<FieldQuery>,
filter: Vec<FieldQuery>,
) -> Self {
BoolQuery {
must,
must_not,
should,
filter,
minimum_should_match: 1_u8,
}
}
}
//实现jsonvalue
impl Into<JsonValue> for BoolQuery {
fn into(self) -> JsonValue {
let mut obj: Object = Object::new();
//must
if !self.must.is_empty() {
let arr = self
.must
.into_iter()
.map(|i| Into::<JsonValue>::into(i))
.collect::<Vec<JsonValue>>();
obj.insert("must", JsonValue::Array(arr));
}
//must not
if !self.must_not.is_empty() {
let arr = self
.must_not
.into_iter()
.map(|i| Into::<JsonValue>::into(i))
.collect::<Vec<JsonValue>>();
obj.insert("must_not", JsonValue::Array(arr));
}
//should
if !self.should.is_empty() {
let arr = self
.should
.into_iter()
.map(|i| Into::<JsonValue>::into(i))
.collect::<Vec<JsonValue>>();
obj.insert("should", JsonValue::Array(arr));
obj.insert(
"minimum_should_match",
JsonValue::Number(Number::from(self.minimum_should_match)),
);
}
//filter
if !self.filter.is_empty() {
let arr = self
.filter
.into_iter()
.map(|i| Into::<JsonValue>::into(i))
.collect::<Vec<JsonValue>>();
obj.insert("filter", JsonValue::Array(arr));
}
json::JsonValue::Object(obj)
}
}
//文档结构
#[derive(Debug, Serialize, Deserialize)]
pub struct EsDoc<D> {
pub _index: String,
pub _type: String,
pub _id: String,
pub _version: i16,
pub _seq_no: i16,
pub _primary_term: i16,
pub found: bool,
pub _source: D,
}
// 根据id查询多个返回数据结构
#[derive(Debug, Serialize, Deserialize)]
pub struct Docs<D> {
pub docs: Vec<EsDoc<D>>,
}
//添加的文档实现这个trait,返回添加文档的id,返回None,es自动生成文档的id
pub trait EsId {
fn id(&self) -> Option<String>;
}
//搜索search 结果json结构
#[derive(Deserialize, Serialize, Debug)]
pub struct SearchResult<D> {
pub took: u32, //耗时 ms
pub timed_out: bool, //是否超时
pub hits: HitsObj<D>,
}
//命中对象结构
#[derive(Deserialize, Serialize, Debug)]
pub struct HitsObj<D> {
pub total: TotalObj, //总数
pub max_score: Option<f32>, //最大得分
pub hits: Vec<HitObj<D>>, //命中文档列表
}
#[derive(Deserialize, Serialize, Debug)]
pub struct TotalObj {
pub value: u64,
pub relation: Option<String>,
}
//命中文档对象
#[derive(Deserialize, Serialize, Debug)]
pub struct HitObj<D> {
pub _index: String,
pub _type: String,
pub _id: String, //es id
pub _score: Option<f32>, //得分
pub _source: D, //文档对象
pub highlight: Option<HashMap<String, Vec<String>>>,
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 12:02:51
/// @Description: 创建客户端
pub async fn get_client_by_url(url: &str) -> EsResult<Elasticsearch> {
let transport = check_result(Transport::single_node(url))?;
let client = Elasticsearch::new(transport);
Ok(client)
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 12:05:08
/// @Description: 创建客户端
pub async fn get_client_by_pool(url: &str) -> EsResult<Elasticsearch> {
let url = check_result(Url::parse(url))?;
let conn_pool = SingleNodeConnectionPool::new(url);
let transport = check_result(TransportBuilder::new(conn_pool).disable_proxy().build())?;
let client = Elasticsearch::new(transport);
Ok(client)
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 13:44:15
/// @Description: 建索引
pub async fn create_index(
client: &Elasticsearch,
index_name: &str,
es_fields: &Vec<EsField>,
) -> EsResult<()> {
//settings
let settings: serde_json::Value = json!({
"number_of_shards": 3,
"number_of_replicas": 0,
"analysis": {
"analyzer": {
"html_text_analyzer": {
"tokenizer": "ik_max_word",
"char_filter": [
"html_strip"
]
}
}
}
});
//mappings
let mappings = create_mappings(es_fields);
let mappings = check_result(serde_json::from_str::<Value>(&mappings))?;
let body = json!({"settings": settings, "mappings": mappings});
let r = client
.indices()
.create(IndicesCreateParts::Index(index_name))
.body(body)
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 删除索引
pub async fn delete_index(client: &Elasticsearch, index_name: &str) -> EsResult<()> {
let r = client
.indices()
.delete(IndicesDeleteParts::Index(&[index_name]))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 清空
pub async fn clear(client: &Elasticsearch, index_name: &str) -> EsResult<()> {
let index_names = [index_name];
let delete_parts = elasticsearch::DeleteByQueryParts::Index(&index_names);
//查询删除 匹所有
let q_json = json!({"query":{"match_all": {}}});
let r = client
.delete_by_query(delete_parts)
.conflicts(Conflicts::Proceed)
.refresh(true)
.body(q_json)
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 是否存在
pub async fn exists(client: &Elasticsearch, index_name: &str) -> EsResult<bool> {
let index_names = [index_name];
let exists_parts = elasticsearch::indices::IndicesExistsParts::Index(&index_names);
let r = client.indices().exists(exists_parts).send().await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
if let Ok(_) = r {
Ok(true)
} else {
Ok(false)
}
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 添加一篇文档
pub async fn insert_doc<T: Serialize>(
client: &Elasticsearch,
index_name: &str,
id: &str,
doc: T,
) -> EsResult<()> {
// let body = json::stringify(doc);
// let body_value = check_result(serde_json::from_str::<Value>(&body))?;
let r = client
.index(elasticsearch::IndexParts::IndexId(index_name, id))
.refresh(elasticsearch::params::Refresh::True)
.body(doc)
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 更新一篇文档
pub async fn update_by_id<T: Serialize>(
client: &Elasticsearch,
index_name: &str,
id: &str,
doc: T,
) -> EsResult<()> {
// let body = json::stringify(doc);
// let body_value = check_result(serde_json::from_str::<Value>(&body))?;
let r = client
.update(elasticsearch::UpdateParts::IndexId(index_name, id))
.refresh(elasticsearch::params::Refresh::True)
.body(json!({"doc": doc}))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 更新某个字段
pub async fn update_value_by_id(
client: &Elasticsearch,
index_name: &str,
id: &str,
field_name: &str, //字段名
value: &str, //字段值
) -> EsResult<()> {
let r = client
.update(elasticsearch::UpdateParts::IndexId(index_name, id))
.refresh(elasticsearch::params::Refresh::True)
.body(json!({"doc": {field_name: value}}))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 查询一篇文档
pub async fn get_source_by_id<DOC>(
client: &Elasticsearch,
index_name: &str,
id: &str,
) -> EsResult<DOC>
where
DOC: for<'de> serde::Deserialize<'de>,
{
let r = client
.get_source(elasticsearch::GetSourceParts::IndexId(index_name, id))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let r = check_result(r)?;
let doc = check_result(r.json::<DOC>().await)?;
Ok(doc)
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 查询一篇文档
pub async fn get_source_by_ids<DOC>(
client: &Elasticsearch,
index_name: &str,
ids: &Vec<String>,
) -> EsResult<Vec<DOC>>
where
DOC: for<'de> serde::Deserialize<'de>,
{
let r = client
.mget(elasticsearch::MgetParts::Index(index_name))
.body(json!({"ids": ids}))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let r = check_result(r)?;
let doc = check_result(r.json::<Docs<DOC>>().await)?;
// println!("{}", r.text().await.unwrap());
let mut vec = vec![];
for doc in doc.docs {
let source = doc._source;
vec.push(source);
}
Ok(vec)
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 删除
pub async fn delete_by_id(client: &Elasticsearch, index_name: &str, id: &str) -> EsResult<()> {
let r = client
.delete(elasticsearch::DeleteParts::IndexId(index_name, id))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 16:31:50
/// @Description: 删除
pub async fn delete_by_ids(
client: &Elasticsearch,
index_name: &str,
ids: &Vec<String>,
) -> EsResult<()> {
let bulk_parts = elasticsearch::BulkParts::Index(index_name);
let delete_lines = ids
.iter()
.map(|id| json!({"delete": {"_id": id}}).to_string())
.collect::<Vec<String>>();
//bulk 批量操作 : https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-bulk.html
let r = client.bulk(bulk_parts).body(delete_lines).send().await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-29 09:05:48
/// @Description: 批量添加, es批量添加数据格式(两行为一组,第一行指定索引id(也可为空),第二行为实际的数据体。):
/// {"index":{"_id":"1"}}
///{"account_number":1,"balance":39225,"firstname":"Amber","lastname":"Duke","age":32,"gender":"M","address":"880 Holmes Lane","employer":"Pyrami","email":"amberduke@pyrami.com","city":"Brogan","state":"IL"}
///
pub async fn insert_docs<T: Serialize + EsId>(
client: &Elasticsearch,
index_name: &str,
docs: &Vec<T>,
) -> EsResult<()> {
let bulk_parts = elasticsearch::BulkParts::Index(index_name);
let index_lines = docs
.iter()
.map(|doc| {
let line1 = json!({"index": {"_id": doc.id()}}).to_string();
let line2 = serde_json::to_string(doc).unwrap();
format!("{}\n{}", line1, line2)
})
.collect::<Vec<String>>();
let r = client.bulk(bulk_parts).body(index_lines).send().await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-29 10:33:11
/// @Description: 计数
pub async fn count(client: &Elasticsearch, index_name: &str) -> EsResult<u64> {
let r = client
.count(elasticsearch::CountParts::Index(&[index_name]))
.send()
.await;
let r = check_result(r)?;
let s = check_result(r.text().await)?;
let j_v = check_result(json::parse(s.as_str()))?;
let count = j_v["count"].as_u64();
if let Some(c) = count {
Ok(c)
} else {
Ok(0)
}
// let r = r.error_for_status_code();
// let _ = check_result(r)?;
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-29 10:43:19
/// @Description: 重建索引
/// https://www.elastic.co/guide/en/elasticsearch/reference/7.17/docs-reindex.html
pub async fn re_index(
client: &Elasticsearch,
source_index: &str,
dest_index: &str,
) -> EsResult<()> {
let r = client
.reindex()
.body(json!({
"source": {
"index": source_index
},
"dest": {
"index": dest_index
}
}))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-29 10:50:05
/// @Description: 根据某个字段删除
pub async fn delete_by_term_query(
client: &Elasticsearch,
index_name: &str,
field_name: &str,
field_value: &str,
) -> EsResult<()> {
let r = client
.delete_by_query(elasticsearch::DeleteByQueryParts::Index(&[index_name]))
.body(json!({
"query": {
"term": {
field_name: field_value
}
}
}))
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.error_for_status_code();
let _ = check_result(r)?;
Ok(())
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-29 10:50:05
/// @Description: 查询
pub async fn search_by_term_query<DOC>(
client: &Elasticsearch,
index_name: &str,
field_name: &str,
field_value: &str,
from: i64,
size: i64,
) -> EsResult<SearchResult<DOC>>
where
DOC: for<'de> serde::Deserialize<'de>,
{
let r = client
.search(elasticsearch::SearchParts::Index(&[index_name]))
.track_total_hits(true)
.from(from)
.size(size)
// ._source(&["id", "title"]) //需要哪些字段
._source(&["true"]) //所有字段
// ._source(&["false"]) //不返回_source的任何字段
.sort(&["_score:desc"]) //排序 数字类型
.body(json!({
"query": {
"term": {
field_name: field_value
}
}
}))
.send()
.await;
let r = check_result(r)?;
let r = r.json::<SearchResult<DOC>>().await;
// println!("{}", r.text().await.unwrap());
// let r = r.error_for_status_code();
// let _ = check_result(r)?;
let r = check_result(r)?;
Ok(r)
}
/// @Author: DengLibin
/// @Date: Create in 2024-04-01 11:24:56
/// @Description: bool查询
pub async fn search_by_bool_query<DOC>(
client: &Elasticsearch,
index_name: &str,
bool_query: BoolQuery,
from: i64,
size: i64,
) -> EsResult<SearchResult<DOC>>
// ) -> EsResult<()>
where
DOC: for<'de> serde::Deserialize<'de>,
{
let bool_q = serde_json::from_str::<Value>(json::stringify(bool_query).as_str()).unwrap();
let body = json!({
"query": {
"bool": bool_q
}
});
println!("查询参数:{}", body);
let r = client
.search(elasticsearch::SearchParts::Index(&[index_name]))
.track_total_hits(true) //返回总数
.from(from)
.size(size)
// ._source(&["id", "name"]) //需要哪些字段
._source(&["true"]) //所有字段
._source_excludes(&["my_vec"]) //排除字段
// ._source(&["false"]) //不返回_source的任何字段
.sort(&["_score:desc"]) //排序 数字类型
.body(body)
.send()
.await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.json::<SearchResult<DOC>>().await;
let r = check_result(r)?;
Ok(r)
}
//查询参数
pub struct BoolQueryParam {
pub index_names: Vec<String>,
pub bool_query: BoolQuery,
pub from: i64,
pub size: i64,
pub exclude_fileds: Vec<String>, //排除的字段
pub sort: Vec<String>, //排序(数字类型字段才能排序) 如: _score:desc
pub highlight_files: Vec<String>, //高亮字段
}
impl BoolQueryParam {
pub fn new(index_names: Vec<String>, bool_query: BoolQuery) -> Self {
BoolQueryParam {
index_names,
bool_query,
from: 0,
size: 10,
exclude_fileds: vec![],
sort: vec![],
highlight_files: vec![],
}
}
}
/// @Author: DengLibin
/// @Date: Create in 2024-04-01 11:24:56
/// @Description: bool查询
pub async fn search_by_param<DOC>(
client: &Elasticsearch,
param: BoolQueryParam,
) -> EsResult<SearchResult<DOC>>
// ) -> EsResult<()>
where
DOC: for<'de> serde::Deserialize<'de>,
{
//查询参数
let bool_q = serde_json::from_str::<Value>(json::stringify(param.bool_query).as_str()).unwrap();
//高亮
let mut h_s = r#" {
"pre_tags": [
"<myy_font style='color:red'>"
],
"post_tags": [
"</myy_font>"
]"#
.replace("\n", "").replace(" ", "").to_string();
if !param.highlight_files.is_empty() {
let mut highlight_fileds = Object::new();
for filed in param.highlight_files.iter() {
highlight_fileds.insert(&filed, Object::new().into());
}
let highlight_fields = json::stringify(highlight_fileds);
// h_s = format!("{},fields:{}}}", h_s, highlight_fields);
h_s.push_str(",\"fields\":");
h_s.push_str(highlight_fields.as_str());
}
h_s.push_str("}");
println!("高亮:{}", h_s);
let v = serde_json::from_str::<Value>(h_s.as_str()).unwrap();
let body = json!({
"highlight": v,
"query": {
"bool": bool_q
}
});
println!("查询参数:{}", body);
let names = param
.index_names
.iter()
.map(|i| i.as_str())
.collect::<Vec<&str>>();
let names = names.as_slice();
let mut s = client.search(elasticsearch::SearchParts::Index(names));
s = s.track_total_hits(true); //返回总数
s = s.from(param.from);
s = s.size(param.size);
// ._source(&["id", "name"]) //需要哪些字段
s = s._source(&["true"]); //所有字段 , ._source(&["false"]) //不返回_source的任何字段
//排序
let sorts = param.sort.iter().map(|i| i.as_str()).collect::<Vec<&str>>();
let sorts = sorts.as_slice();
if !sorts.is_empty() {
s = s.sort(sorts); //排序
}
//排除字段
let excludes = param
.exclude_fileds
.iter()
.map(|i| i.as_str())
.collect::<Vec<&str>>();
let excludes = excludes.as_slice();
if !excludes.is_empty() {
s = s._source_excludes(excludes) //排除字段
}
//高亮
//
let r = s.body(body).send().await;
let r = check_result(r)?;
// println!("{}", r.text().await.unwrap());
let r = r.json::<SearchResult<DOC>>().await;
let r = check_result(r)?;
Ok(r)
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 13:50:06
/// @Description: 根据字段创建mappings 返回json字符串(对象类型)
/// {
/// "properties": {
/// "field1": { "type": "text" }
/// }
/// }
///
///
///
fn create_mappings(es_fields: &Vec<EsField>) -> String {
let mut mappings_obj = Object::new();
let mut properties_obj = Object::new();
for field in es_fields {
properties_obj.insert(&field.name, field.filed_type.clone().into());
}
mappings_obj.insert("properties", properties_obj.into());
json::stringify(mappings_obj)
}
3.单元测试
//! @Author: DengLibin
//! @Date: Create in 2024-03-28 14:04:50
//! @Description:
//!
#[cfg(feature = "es")]
#[cfg(test)]
mod tests {
use rust_common::es::{self, BoolQuery, BoolQueryParam, EsId, FieldQuery, QueryType, RangeValue};
use serde::{ Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct TitleContent{
id: Option<String>,
title: Option<String>,
content: Option<String>
}
impl EsId for TitleContent {
fn id(&self)->Option<String> {
self.id.clone()
}
}
/// @Author: DengLibin
/// @Date: Create in 2024-03-28 14:19:15
/// @Description: 测试创建es索引
#[test]
pub fn test_create_index() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
//department,title,ask,answer
let text_field_type = es::EsFieldType {
type_name: "text".into(),
store: true,
index: true,
dims: 0,
};
//标题
let title_field = es::EsField {
name: "title".into(),
filed_type: text_field_type.clone(),
};
let department_field = es::EsField {
name: "department".into(),
filed_type: text_field_type.clone(),
};
let ask_field = es::EsField {
name: "ask".into(),
filed_type: text_field_type.clone(),
};
let answer_field = es::EsField {
name: "answer".into(),
filed_type: text_field_type.clone(),
};
//向量类型
let mut vec_type = text_field_type.clone();
vec_type.type_name = "dense_vector".into();
vec_type.dims = 1024;
let ask_vec_field = es::EsField {
name: "ask_vec".into(),
filed_type: vec_type,
};
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200")
.await
.unwrap();
println!("创建esclient成功");
let r = es::create_index(
&client,
"medical_qa",
&vec![
title_field,
department_field,
ask_field,
answer_field,
ask_vec_field,
],
)
.await;
match r {
Ok(_) => {
println!("创建成功");
}
Err(e) => {
println!("创建失败:{}", e);
}
}
});
}
#[test]
pub fn test_create_index2() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
//department,title,ask,answer
let text_field_type = es::EsFieldType {
type_name: "text".into(),
store: true,
index: true,
dims: 0,
};
//标题
let title_field = es::EsField {
name: "title".into(),
filed_type: text_field_type.clone(),
};
let content_field = es::EsField {
name: "content".into(),
filed_type: text_field_type.clone(),
};
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200")
.await
.unwrap();
println!("创建esclient成功");
let r =
es::create_index(&client, "title_content", &vec![title_field, content_field]).await;
match r {
Ok(_) => {
println!("创建成功");
}
Err(e) => {
println!("创建失败:{}", e);
}
}
});
}
#[test]
pub fn test_delete_index() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200")
.await
.unwrap();
let r = es::delete_index(&client, "qa").await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_exists_index() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200")
.await
.unwrap();
let r = es::exists(&client, "yiscn-table-525029568336005_3").await;
match r {
Ok(b) => {
println!("成功:{}", b);
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_clear_index() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200")
.await
.unwrap();
let r = es::clear(&client, "yiscn-table-489985698672773").await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_insert_doc() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let content = r#"黎明诗唱片专辑封面
当年,黎明诗凭借甜美的外表、美好的身材,成为很多少男心目中的女神,而她也曾有过一段选美经历。据了解,她在英国读书时,
曾同妹妹一起参选当地的华裔小姐选美,分别获得亚军和季军。后来黎明诗随家人回到香港,参演了《霸王花》等作品。2017年,黎明诗参加活动 图据:视觉中国
1990年,黎明诗被唱片公司看中,推出了多个专辑。因为她长得甜美、清纯,而被称为“玉女歌手”,代表作有《Goodbye My Love》
《流离的爱》《停不了的爱》《爱上不爱我的人》等。在生活中,热爱交朋友的她,当时与梅艳芳是好闺蜜。"#;
let title_content = TitleContent{
id: Some("2".into()),
title: Some("一代玉女歌手黎明诗去世,抗癌大半年,在睡梦中离开".into()),
content: Some(content.into())
};
let r = es::insert_doc(&client, "title_content", "2", title_content).await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_update_doc() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let content = r#"黎明诗唱片专辑封面
当年,黎明诗凭借甜美的外表、美好的身材,成为很多少男心目中的女神,而她也曾有过一段选美经历。据了解,她在英国读书时,
曾同妹妹一起参选当地的华裔小姐选美,分别获得亚军和季军。后来黎明诗随家人回到香港,参演了《霸王花》等作品。2017年,黎明诗参加活动 图据:视觉中国
1990年,黎明诗被唱片公司看中,推出了多个专辑。因为她长得甜美、清纯,而被称为“玉女歌手”,代表作有《Goodbye My Love》
《流离的爱》《停不了的爱》《爱上不爱我的人》等。在生活中,热爱交朋友的她,当时与梅艳芳是好闺蜜。"#;
let title_content = TitleContent{
id: Some("1".into()),
title: Some("一代玉女歌手黎明诗去世".into()),
content: Some(content.into())
};
let r = es::update_by_id(&client, "title_content", "1", title_content).await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_update_value_doc() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::update_value_by_id(&client, "title_content", "1", "title", "明诗凭借甜美的外表、美好的身材,成为很多少男心目中的女神").await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_get_source_by_id() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::get_source_by_id::<TitleContent>(&client, "title_content", "1").await;
match r {
Ok(title_conent) => {
println!("成功:{:?}", title_conent);
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_get_source_by_ids() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::get_source_by_ids::<TitleContent>(&client, "title_content", &vec!["1".into(), "2".into()]).await;
match r {
Ok(title_conents) => {
println!("成功:{:?}", title_conents);
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn delete_by_id() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::delete_by_id(&client, "title_content", "2").await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_delete_by_ids() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::delete_by_ids(&client, "title_content", &vec!["1".into(), "2".into()]).await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_insert_docs() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let doc1 = TitleContent {
id: None,
title: Some("新华社权威速览 | 关于中美关系、中国经济,习近平主席最新论述".into()),
content: Some("3月27日,国家主席习近平在北京人民大会堂集体会见美国工商界和战略学术界代表。会见中,习近平主席围绕中美关系、中国经济作出哪些重要论述?一起来看。".into())
};
let doc2 = TitleContent {
id: None,
title: Some("习语|把人们隔开的不是千山万水,而是相互认知上的隔膜".into()),
content: Some("把人们隔开的往往不是千山万水,不是大海深壑,而是人们相互认知上的隔膜。”十年前的3月28日,习近平主席在德国柏林演讲时的这番话,如今听来依然充满深意。".into())
};
let r = es::insert_docs(&client, "title_content", &vec![doc1, doc2]).await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_count() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::count(&client, "title_content").await;
match r {
Ok(count) => {
println!("成功:{}", count);
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_delete_by_term_query() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
let r = es::delete_by_term_query(&client, "title_content", "id", "2").await;
match r {
Ok(_) => {
println!("成功");
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[derive(Debug, Serialize, Deserialize)]
pub struct YiscnDoc{
collect_batch_no: Option<String>,
department: Option<String>,
name: Option<String>,
yiscn_server_id: Option<String>,
yiscn_table_info_id: Option<String>,
yiscn_create_user_name: Option<String>,
yiscn_audit_status: Option<i8>,
yiscn_create_time: Option<String>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ImgVec{
title: Option<String>, //标题
my_vec: Option<Vec<f64>>, //向量
}
#[test]
pub fn test_search_by_term_query() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://192.168.6.199:9200").await.unwrap();
let r = es::search_by_term_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", "yiscn_secret_grade", "0", 1, 10).await;
match r {
Ok(result) => {
println!("成功:{}", serde_json::to_string(&result).unwrap());
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_search_by_bool_query() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://192.168.6.199:9200").await.unwrap();
// let r = es::search_by_term_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", "yiscn_secret_grade", "0", 1, 10).await;
let field_query = FieldQuery::new(QueryType::Term, "yiscn_secret_grade".into(), Some("0".into()));
let mut bool_query: BoolQuery = BoolQuery::new();
bool_query.must.push(field_query);
bool_query.must.push(FieldQuery::new(QueryType::Match,"name".into(), Some("关键技术".into())));
bool_query.must.push(FieldQuery::new( QueryType::MatchPhrase,"name".into(),Some("物联网关键技术公示名单".into())));
bool_query.must.push(FieldQuery::new(QueryType::Exists, "name".into(), None));
//id in查询
bool_query.must.push(FieldQuery::new( QueryType::Terms, "_id".into(), Some(vec!["a0fdffd23a4c48a24caf0e6fe660f90b".to_string(),"2345".to_string(), "ee5025966e7237720df1b47035e62c66".to_string()].into())));
//范围查询
let range = RangeValue{gte: Some(1700824124460_u64.into()), lte: Some(1700824124461_u64.into())};
bool_query.must.push(FieldQuery::new( QueryType::Range, "yiscn_create_time".into(), Some(range.into())));
let r = es::search_by_bool_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", bool_query, 0, 5).await;
match r {
Ok(result) => {
println!("成功:{}", serde_json::to_string(&result).unwrap());
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_search_by_vec_query() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://127.0.0.1:9200").await.unwrap();
// let r = es::search_by_term_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", "yiscn_secret_grade", "0", 1, 10).await;
let mut bool_query: BoolQuery = BoolQuery::new();
let vec: Vec<f64> = vec![0.8313725490196079,0.8666666666666667,0.8666666666666667,0.8666666666666667,0.8588235294117647,0.8549019607843137,0.8352941176470589,0.8196078431372549,0.8,0.7764705882352941,0.7490196078431373,0.7215686274509804,0.7176470588235294,0.6745098039215687,0.6705882352941176,0.6627450980392157,0.6470588235294118,0.6352941176470588,0.615686274509804,0.6196078431372549,0.615686274509804,0.6235294117647059,0.6235294117647059,0.6274509803921569,0.6352941176470588,0.6313725490196078,0.6392156862745098,0.6431372549019608,0.6392156862745098,0.6431372549019608,0.6431372549019608,0.6431372549019608,0.796078431372549,0.8666666666666667,0.8666666666666667,0.8666666666666667,0.8588235294117647,0.8627450980392157,0.8509803921568627,0.8352941176470589,0.8196078431372549,0.796078431372549,0.7803921568627451,0.7568627450980392,0.7411764705882353,0.7176470588235294,0.6941176470588235,0.7058823529411765,0.6901960784313725,0.6823529411764706,0.6823529411764706,0.6784313725490196,0.6823529411764706,0.6784313725490196,0.6745098039215687,0.6784313725490196,0.6745098039215687,0.6745098039215687,0.6784313725490196,0.6745098039215687,0.6784313725490196,0.6745098039215687,0.6705882352941176,0.6666666666666666,0.7098039215686275,0.8588235294117647,0.8666666666666667,0.8666666666666667,0.8666666666666667,0.8627450980392157,0.8627450980392157,0.8627450980392157,0.8352941176470589,0.8117647058823529,0.8,0.788235294117647,0.7725490196078432,0.7568627450980392,0.7529411764705882,0.7529411764705882,0.7450980392156863,0.7490196078431373,0.7490196078431373,0.7450980392156863,0.7411764705882353,0.7411764705882353,0.7411764705882353,0.7411764705882353,0.7333333333333333,0.7294117647058823,0.7215686274509804,0.7215686274509804,0.7176470588235294,0.7098039215686275,0.6980392156862745,0.6862745098039216,0.4588235294117647,0.8431372549019608,0.8745098039215686,0.8784313725490196,0.8823529411764706,0.8784313725490196,0.8549019607843137,0.803921568627451,0.8117647058823529,0.8274509803921568,0.8392156862745098,0.8823529411764706,0.8549019607843137,0.8392156862745098,0.8549019607843137,0.8274509803921568,0.7686274509803922,0.7764705882352941,0.7764705882352941,0.7764705882352941,0.7764705882352941,0.7725490196078432,0.7764705882352941,0.7725490196078432,0.7686274509803922,0.7686274509803922,0.7607843137254902,0.7647058823529411,0.7686274509803922,0.7490196078431373,0.7411764705882353,0.7411764705882353,0.3843137254901961,0.6627450980392157,0.8901960784313725,0.8666666666666667,0.8431372549019608,0.7490196078431373,0.8392156862745098,0.8235294117647058,0.6941176470588235,0.6509803921568628,0.7176470588235294,0.7607843137254902,0.7333333333333333,0.7215686274509804,0.8117647058823529,0.8784313725490196,0.8313725490196079,0.8196078431372549,0.807843137254902,0.8117647058823529,0.8117647058823529,0.796078431372549,0.796078431372549,0.796078431372549,0.788235294117647,0.796078431372549,0.788235294117647,0.796078431372549,0.788235294117647,0.7764705882352941,0.7725490196078432,0.43137254901960789,0.38823529411764709,0.7058823529411765,0.8588235294117647,0.7686274509803922,0.8,0.7803921568627451,0.5294117647058824,0.7098039215686275,0.7607843137254902,0.7647058823529411,0.7725490196078432,0.788235294117647,0.807843137254902,0.8117647058823529,0.8117647058823529,0.7607843137254902,0.7803921568627451,0.8392156862745098,0.8431372549019608,0.8274509803921568,0.8235294117647058,0.796078431372549,0.788235294117647,0.796078431372549,0.8,0.8352941176470589,0.8,0.8,0.8117647058823529,0.8,0.615686274509804,0.3215686274509804,0.36470588235294118,0.8431372549019608,0.8117647058823529,0.807843137254902,0.44313725490196079,0.5647058823529412,0.6941176470588235,0.7058823529411765,0.7019607843137254,0.7019607843137254,0.23921568627450982,0.20784313725490198,0.1803921568627451,0.23137254901960786,0.2196078431372549,0.14901960784313726,0.12941176470588237,0.2,0.24705882352941178,0.7568627450980392,0.4980392156862745,0.8666666666666667,0.8745098039215686,0.8784313725490196,0.8823529411764706,0.8666666666666667,0.8666666666666667,0.8235294117647058,0.8666666666666667,0.8392156862745098,0.6980392156862745,0.3058823529411765,0.6862745098039216,0.8627450980392157,0.6549019607843137,0.7098039215686275,0.4980392156862745,0.6470588235294118,0.6941176470588235,0.19215686274509806,0.15294117647058826,0.1803921568627451,0.19215686274509806,0.18823529411764707,0.21568627450980394,0.4823529411764706,0.7215686274509804,0.7607843137254902,0.5607843137254902,0.8431372549019608,0.7333333333333333,0.49019607843137255,0.27450980392156867,0.25098039215686276,0.2784313725490196,0.5568627450980392,0.8588235294117647,0.8745098039215686,0.8588235294117647,0.8588235294117647,0.8588235294117647,0.8274509803921568,0.7450980392156863,0.3803921568627451,0.6549019607843137,0.8745098039215686,0.7333333333333333,0.4,0.49411764705882357,0.13333333333333334,0.07450980392156863,0.10588235294117647,0.17647058823529414,0.12941176470588237,0.15294117647058826,0.16470588235294118,0.20784313725490198,0.22745098039215687,0.1450980392156863,0.10588235294117647,0.1803921568627451,0.4549019607843137,0.8980392156862745,0.6666666666666666,0.19215686274509806,0.4980392156862745,0.7294117647058823,0.35294117647058828,0.23137254901960786,0.27450980392156867,0.6941176470588235,0.8823529411764706,0.8745098039215686,0.8549019607843137,0.796078431372549,0.18823529411764707,0.8901960784313725,0.8901960784313725,0.7568627450980392,0.3843137254901961,0.0784313725490196,0.07450980392156863,0.17254901960784314,0.09411764705882353,0.11372549019607843,0.12549019607843138,1.1764705882352941e-2,1.1764705882352941e-2,0.03529411764705882,0.08627450980392157,0.2,0.5372549019607843,0.7215686274509804,0.5607843137254902,0.06274509803921569,4.7058823529411767e-2,5.4901960784313728e-2,0.11764705882352941,0.5215686274509804,0.15294117647058826,0.36470588235294118,0.30980392156862748,0.2196078431372549,0.29411764705882356,0.8745098039215686,0.8235294117647058,0.7725490196078432,0.07058823529411765,0.8901960784313725,0.8862745098039215,0.8274509803921568,5.8823529411764708e-2,5.8823529411764708e-2,0.11764705882352941,0.10588235294117647,0.08627450980392157,1.1764705882352941e-2,5.8823529411764708e-2,0.09411764705882353,0.1450980392156863,0.5058823529411765,0.1568627450980392,0.5686274509803921,0.34509803921568629,0.42745098039215687,0.32941176470588237,0.36470588235294118,0.16862745098039218,0.4,0.2196078431372549,0.06274509803921569,4.7058823529411767e-2,0.32941176470588237,0.2,0.23529411764705883,0.20784313725490198,0.24705882352941178,0.10980392156862745,0.16862745098039218,0.03137254901960784,0.8901960784313725,0.8901960784313725,0.09019607843137255,4.3137254901960787e-2,0.17254901960784314,0.1450980392156863,2.3529411764705883e-2,2.3529411764705883e-2,4.3137254901960787e-2,0.07058823529411765,0.5411764705882353,0.5529411764705883,4.7058823529411767e-2,0.7764705882352941,0.49411764705882357,0.16470588235294118,0.4745098039215686,0.07058823529411765,0.6666666666666666,0.5529411764705883,0.23529411764705883,0.3254901960784314,0.18823529411764707,0.12549019607843138,0.06274509803921569,0.09019607843137255,0.17647058823529414,0.25882352941176475,0.25098039215686276,0.2,0.14901960784313726,0.09411764705882353,0.8901960784313725,0.2980392156862745,4.7058823529411767e-2,0.13725490196078433,0.13725490196078433,0.0392156862745098,0.0196078431372549,0.1803921568627451,0.12941176470588237,0.4745098039215686,0.5450980392156862,0.7725490196078432,0.6352941176470588,0.25098039215686276,0.26666666666666669,0.34901960784313726,0.5098039215686274,0.8862745098039215,0.11372549019607843,0.11764705882352941,0.6431372549019608,0.17254901960784314,0.24705882352941178,0.22745098039215687,0.1450980392156863,0.11372549019607843,0.03137254901960784,0.27450980392156867,0.23529411764705883,0.21568627450980394,0.10588235294117647,0.1568627450980392,0.8980392156862745,0.17254901960784314,4.3137254901960787e-2,0.10588235294117647,0.10980392156862745,0.0196078431372549,0.11372549019607843,0.1568627450980392,0.43137254901960789,0.2823529411764706,0.4549019607843137,0.6627450980392157,0.21176470588235295,0.30196078431372549,0.3333333333333333,0.49411764705882357,0.7450980392156863,0.6941176470588235,0.09803921568627451,0.09803921568627451,0.5137254901960784,0.25098039215686276,0.22745098039215687,0.5019607843137255,0.1607843137254902,0.17254901960784314,0.12941176470588237,2.7450980392156864e-2,0.2980392156862745,0.23921568627450982,0.2,0.11764705882352941,0.9058823529411765,0.06666666666666667,0.06666666666666667,0.12941176470588237,2.3529411764705883e-2,0.0196078431372549,0.11372549019607843,0.23921568627450982,0.3411764705882353,0.23529411764705883,0.42745098039215687,0.23137254901960786,0.2901960784313726,0.41568627450980397,0.1568627450980392,0.2627450980392157,0.23137254901960786,0.23921568627450982,0.1803921568627451,0.2,0.12549019607843138,0.5176470588235295,0.615686274509804,0.3058823529411765,0.1568627450980392,0.1803921568627451,0.08235294117647059,0.11764705882352941,0.03529411764705882,0.2627450980392157,0.4588235294117647,0.10588235294117647,0.39215686274509806,5.8823529411764708e-2,0.08235294117647059,0.1568627450980392,2.3529411764705883e-2,0.11764705882352941,0.2,0.2196078431372549,0.2549019607843137,0.36470588235294118,0.1803921568627451,0.2196078431372549,0.11372549019607843,0.13333333333333334,0.21176470588235295,0.45098039215686278,0.29411764705882356,0.2196078431372549,0.23529411764705883,0.1607843137254902,2.3529411764705883e-2,0.36470588235294118,0.6,0.24705882352941178,0.23529411764705883,0.19607843137254903,0.09411764705882353,0.1411764705882353,0.10588235294117647,0.09803921568627451,0.14901960784313726,0.16470588235294118,0.43137254901960789,0.10980392156862745,0.08235294117647059,0.13333333333333334,2.3529411764705883e-2,0.25882352941176475,0.3215686274509804,0.15294117647058826,0.19215686274509806,0.21176470588235295,0.19215686274509806,0.10588235294117647,0.19215686274509806,0.6274509803921569,0.20784313725490198,0.5450980392156862,0.5725490196078431,0.4392156862745098,0.33725490196078436,0.25882352941176475,0.12549019607843138,0.09411764705882353,0.30980392156862748,0.2,0.19215686274509806,0.17647058823529414,0.11372549019607843,0.14901960784313726,0.10980392156862745,4.7058823529411767e-2,0.23921568627450982,0.36470588235294118,0.8274509803921568,0.29411764705882356,0.09019607843137255,0.1568627450980392,0.01568627450980392,0.18823529411764707,0.28627450980392157,0.27450980392156867,0.12941176470588237,0.21176470588235295,0.19607843137254903,0.1411764705882353,0.3058823529411765,0.2,0.21176470588235295,0.34901960784313726,0.6431372549019608,0.5764705882352941,0.42745098039215687,0.3058823529411765,0.08235294117647059,0.09411764705882353,0.5098039215686274,0.09803921568627451,0.12941176470588237,0.12941176470588237,0.09019607843137255,0.12549019607843138,0.14901960784313726,0.06274509803921569,0.21176470588235295,0.12549019607843138,0.17254901960784314,0.34509803921568629,0.08627450980392157,0.13333333333333334,0.0784313725490196,0.21568627450980394,0.1803921568627451,0.3254901960784314,0.15294117647058826,0.16470588235294118,0.11372549019607843,0.11764705882352941,0.24705882352941178,0.5450980392156862,0.23921568627450982,0.3058823529411765,0.45098039215686278,0.4627450980392157,0.17647058823529414,4.7058823529411767e-2,0.3215686274509804,0.1803921568627451,0.6509803921568628,0.08627450980392157,0.08235294117647059,0.08235294117647059,0.10588235294117647,0.09019607843137255,0.12549019607843138,0.09019607843137255,0.09803921568627451,0.06666666666666667,0.8274509803921568,0.3607843137254902,0.23529411764705883,0.09411764705882353,2.7450980392156864e-2,0.27450980392156867,0.14901960784313726,0.09803921568627451,1.1764705882352941e-2,0.11764705882352941,0.12549019607843138,0.13725490196078433,0.09803921568627451,0.39215686274509806,0.11764705882352941,0.13725490196078433,0.2,0.0392156862745098,0.01568627450980392,5.8823529411764708e-2,0.5215686274509804,0.13333333333333334,0.09411764705882353,0.1450980392156863,0.1568627450980392,0.10980392156862745,0.21568627450980394,0.12941176470588237,0.1411764705882353,0.09411764705882353,0.11764705882352941,0.2196078431372549,0.8666666666666667,0.807843137254902,0.26666666666666669,0.1568627450980392,0.09803921568627451,0.06274509803921569,0.16470588235294118,0.11764705882352941,0.09019607843137255,0.0784313725490196,0.43137254901960789,0.4745098039215686,0.03137254901960784,4.7058823529411767e-2,0.09019607843137255,0.08627450980392157,2.3529411764705883e-2,0.11764705882352941,0.0784313725490196,0.26666666666666669,0.2196078431372549,4.3137254901960787e-2,0.1607843137254902,0.10980392156862745,0.07450980392156863,0.1607843137254902,0.14901960784313726,0.17647058823529414,4.7058823529411767e-2,4.7058823529411767e-2,0.2,0.2196078431372549,0.8666666666666667,0.8666666666666667,0.37254901960784317,0.26666666666666669,0.10980392156862745,0.07450980392156863,0.10588235294117647,0.8509803921568627,4.7058823529411767e-2,0.03137254901960784,0.0392156862745098,0.2196078431372549,2.7450980392156864e-2,0.07058823529411765,0.17647058823529414,0.09803921568627451,0.09803921568627451,0.06666666666666667,0.21568627450980394,0.3254901960784314,0.43137254901960789,0.09803921568627451,0.36470588235294118,0.2196078431372549,5.8823529411764708e-2,0.11764705882352941,0.21176470588235295,0.09803921568627451,0.1803921568627451,4.3137254901960787e-2,0.14901960784313726,0.12941176470588237,0.8666666666666667,0.8666666666666667,0.7803921568627451,0.35294117647058828,0.23921568627450982,0.1411764705882353,0.0196078431372549,0.0196078431372549,0.06666666666666667,2.3529411764705883e-2,5.8823529411764708e-2,0.1607843137254902,0.10980392156862745,0.15294117647058826,0.09411764705882353,0.10980392156862745,0.0392156862745098,0.30980392156862748,0.23137254901960786,0.2784313725490196,0.1568627450980392,0.09803921568627451,0.1450980392156863,0.11764705882352941,0.10588235294117647,4.7058823529411767e-2,0.10588235294117647,0.21568627450980394,0.10588235294117647,0.17647058823529414,0.17254901960784314,0.1607843137254902,0.8666666666666667,0.8588235294117647,0.8745098039215686,0.803921568627451,0.2627450980392157,0.38823529411764709,0.13333333333333334,4.3137254901960787e-2,4.7058823529411767e-2,0.11372549019607843,5.8823529411764708e-2,0.10588235294117647,0.18823529411764707,0.2,0.12549019607843138,5.8823529411764708e-2,0.2901960784313726,0.41568627450980397,0.11764705882352941,0.11372549019607843,0.17254901960784314,0.6627450980392157,0.16470588235294118,0.28627450980392157,0.4117647058823529,4.7058823529411767e-2,0.09019607843137255,0.09019607843137255,0.08627450980392157,0.1450980392156863,0.1450980392156863,0.3137254901960784,0.8784313725490196,0.8745098039215686,0.8745098039215686,0.8666666666666667,0.7529411764705882,0.20784313725490198,0.4823529411764706,0.26666666666666669,0.12549019607843138,0.08627450980392157,0.1568627450980392,0.15294117647058826,0.22745098039215687,0.1803921568627451,0.1607843137254902,0.2784313725490196,0.07450980392156863,0.09803921568627451,0.12549019607843138,0.19215686274509806,0.10588235294117647,0.24705882352941178,0.21176470588235295,0.5215686274509804,0.20784313725490198,5.8823529411764708e-2,0.0196078431372549,0.1411764705882353,0.11764705882352941,0.13333333333333334,0.2784313725490196,0.6313725490196078,0.8901960784313725,0.8784313725490196,0.8745098039215686,0.8745098039215686,0.8666666666666667,0.7176470588235294,0.26666666666666669,0.23921568627450982,0.7333333333333333,0.1803921568627451,0.09803921568627451,0.12549019607843138,0.23529411764705883,0.18823529411764707,0.21176470588235295,0.13333333333333334,0.0392156862745098,0.1568627450980392,0.09411764705882353,0.3411764705882353,0.3254901960784314,0.18823529411764707,0.16470588235294118,0.37254901960784317,0.17254901960784314,0.0392156862745098,0.09803921568627451,0.09803921568627451,0.2196078431372549,0.2901960784313726,0.6784313725490196,0.7098039215686275,0.8823529411764706,0.8901960784313725,0.8745098039215686,0.8666666666666667,0.8666666666666667,0.8470588235294118,0.6823529411764706,0.615686274509804,0.3764705882352941,0.1803921568627451,0.6352941176470588,0.7215686274509804,0.19215686274509806,5.4901960784313728e-2,0.06274509803921569,4.7058823529411767e-2,5.4901960784313728e-2,0.08235294117647059,0.11764705882352941,0.07058823529411765,0.16470588235294118,0.14901960784313726,0.23921568627450982,0.07450980392156863,0.07058823529411765,0.13333333333333334,0.19215686274509806,0.26666666666666669,0.38823529411764709,0.6470588235294118,0.6392156862745098,0.28627450980392157,0.9058823529411765,0.8784313725490196,0.8666666666666667,0.8862745098039215,0.8588235294117647,0.8431372549019608,0.4,0.7529411764705882,0.5725490196078431,0.5098039215686274,0.49019607843137255,0.1568627450980392,0.10588235294117647,0.13725490196078433,0.19215686274509806,0.19215686274509806,0.16470588235294118,0.11764705882352941,0.10588235294117647,0.09803921568627451,0.16470588235294118,0.2,0.22745098039215687,0.23137254901960786,0.21176470588235295,0.2196078431372549,0.4,0.5215686274509804,0.5490196078431373,0.8117647058823529,0.8352941176470589,0.803921568627451,0.9058823529411765,0.8823529411764706,0.8745098039215686,0.8784313725490196,0.8549019607843137,0.8392156862745098,0.07450980392156863,0.12549019607843138,0.8,0.6509803921568628,0.44313725490196079,0.38823529411764709,0.36470588235294118,0.29411764705882356,0.2196078431372549,0.11764705882352941,0.06666666666666667,5.4901960784313728e-2,4.7058823529411767e-2,5.8823529411764708e-2,0.06274509803921569,0.11764705882352941,0.25882352941176475,0.36470588235294118,0.4,0.41568627450980397,0.43137254901960789,0.6313725490196078,0.7803921568627451,0.8235294117647058,0.8392156862745098,0.8274509803921568,0.8901960784313725,0.8823529411764706,0.8901960784313725,0.8745098039215686,0.8509803921568627,0.8117647058823529,0.1568627450980392,0.12941176470588237,0.09803921568627451,0.7333333333333333,0.7098039215686275,0.6901960784313725,0.35294117647058828,0.10588235294117647,0.08235294117647059,0.06666666666666667,0.06666666666666667,5.4901960784313728e-2,0.06274509803921569,0.09019607843137255,0.13333333333333334,0.20784313725490198,0.29411764705882356,0.33725490196078436,0.34901960784313726,0.6392156862745098,0.6980392156862745,0.7176470588235294,0.7411764705882353,0.7450980392156863,0.803921568627451,0.8117647058823529,0.8862745098039215,0.8901960784313725,0.8901960784313725,0.8666666666666667,0.8509803921568627,5.8823529411764708e-2,0.1607843137254902,0.11764705882352941,0.09803921568627451,0.09411764705882353,0.10980392156862745,0.6862745098039216,0.7019607843137254,0.596078431372549,0.43137254901960789,0.3176470588235294,0.1803921568627451,0.16470588235294118,0.11764705882352941,0.18823529411764707,0.30980392156862748,0.4823529411764706,0.47058823529411766,0.7058823529411765,0.7019607843137254,0.7529411764705882,0.7529411764705882,0.7568627450980392,0.796078431372549,0.803921568627451,0.8117647058823529,0.8235294117647058,0.8980392156862745,0.8862745098039215,0.8666666666666667,0.8588235294117647,0.8117647058823529,0.17254901960784314,0.16862745098039218,0.11764705882352941,0.10980392156862745,0.09803921568627451,0.11764705882352941,0.10588235294117647,0.08235294117647059,0.07450980392156863,0.4666666666666667,0.7647058823529411,0.6352941176470588,0.5333333333333333,0.5294117647058824,0.592156862745098,0.7686274509803922,5.4901960784313728e-2,0.06666666666666667,0.03529411764705882,0.6941176470588235,0.7333333333333333,0.7529411764705882,0.788235294117647,0.796078431372549,0.788235294117647,0.807843137254902,0.8352941176470589];
bool_query.must.push(FieldQuery::new(QueryType::Vector, "my_vec".into(), Some(vec.into())));
let r = es::search_by_bool_query::<ImgVec>(&client, "img_vector", bool_query, 0, 5).await;
match r {
Ok(result) => {
println!("成功:{}", serde_json::to_string(&result).unwrap());
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
//bool嵌套查询
#[test]
pub fn test_search_by_bool_bool_query() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://192.168.6.199:9200").await.unwrap();
// let r = es::search_by_term_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", "yiscn_secret_grade", "0", 1, 10).await;
let field_query = FieldQuery::new(QueryType::Term, "yiscn_secret_grade".into(), Some("0".into()));
let mut bool_query: BoolQuery = BoolQuery::new();
bool_query.must.push(field_query);
bool_query.must.push(FieldQuery::new(QueryType::Match,"name".into(), Some("关键技术".into())));
let mut sub_bool = BoolQuery::new();
sub_bool.must.push(FieldQuery::new( QueryType::Term,"yiscn_create_time".into(),Some(1700824175501_u64.into())));
//嵌套一个bool
bool_query.must.push(FieldQuery::new_bool(sub_bool));
let r = es::search_by_bool_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", bool_query, 0, 5).await;
match r {
Ok(result) => {
println!("成功:{}", serde_json::to_string(&result).unwrap());
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
#[test]
pub fn test_search_by_param() {
//异步运行时
let rt = tokio::runtime::Builder::new_current_thread()
.enable_io() // 可在runtime中使用异步IO
.enable_time() // 可在runtime中使用异步计时器(timer)
.build()
.unwrap();
rt.block_on(async {
let client = es::get_client_by_url("http://192.168.6.199:9200").await.unwrap();
// let r = es::search_by_term_query::<YiscnDoc>(&client, "yiscn-table-427778195693701_2", "yiscn_secret_grade", "0", 1, 10).await;
let field_query = FieldQuery::new(QueryType::Term, "yiscn_secret_grade".into(), Some("0".into()));
let mut bool_query: BoolQuery = BoolQuery::new();
bool_query.must.push(field_query);
bool_query.must.push(FieldQuery::new(QueryType::Match,"name".into(), Some("关键技术".into())));
let mut sub_bool = BoolQuery::new();
sub_bool.must.push(FieldQuery::new( QueryType::Term,"yiscn_create_time".into(),Some(1700824175501_u64.into())));
//嵌套一个bool
bool_query.must.push(FieldQuery::new_bool(sub_bool));
let mut param = BoolQueryParam::new(vec!["yiscn-table-427778195693701_2".into()], bool_query);
param.highlight_files.push("name".into());
param.exclude_fileds.push("name".into());
param.sort.push("yiscn_create_time:desc".into());
let r = es::search_by_param::<YiscnDoc>(&client, param).await;
match r {
Ok(result) => {
println!("成功:{}", serde_json::to_string(&result).unwrap());
}
Err(e) => {
println!("失败:{}", e);
}
}
});
}
}