Skip to content

Commit

Permalink
Add support for fuzzy search
Browse files Browse the repository at this point in the history
  • Loading branch information
photino committed Dec 27, 2023
1 parent 12d1571 commit ad552d9
Show file tree
Hide file tree
Showing 31 changed files with 78 additions and 98 deletions.
5 changes: 2 additions & 3 deletions examples/actix-app/src/model/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ pub struct Tag {
// Basic fields.
#[schema(primary_key, read_only, constructor = "Uuid::now_v7")]
id: Uuid,
#[schema(not_null, index_type = "text", comment = "Tag name")]
#[schema(not_null, comment = "Tag name")]
name: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]
description: String,

// Info fields.
#[schema(not_null, comment = "Tag category", index_type = "hash")]
#[schema(not_null, index_type = "hash", comment = "Tag category")]
category: String,
#[schema(snapshot, reference = "Tag", comment = "Optional parent tag")]
parent_id: Option<Uuid>,
Expand Down
5 changes: 2 additions & 3 deletions examples/axum-app/src/model/tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,14 @@ pub struct Tag {
// Basic fields.
#[schema(primary_key, auto_increment, read_only)]
id: i64,
#[schema(not_null, index_type = "text", comment = "Tag name")]
#[schema(not_null, comment = "Tag name")]
name: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]
description: String,

// Info fields.
#[schema(not_null, comment = "Tag category", index_type = "hash")]
#[schema(not_null, index_type = "hash", comment = "Tag category")]
category: String,
#[schema(snapshot, reference = "Tag", comment = "Optional parent tag")]
parent_id: Option<i64>,
Expand Down
11 changes: 5 additions & 6 deletions examples/axum-app/src/model/user.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ pub struct User {
// Basic fields.
#[schema(primary_key, auto_increment, read_only)]
id: i64,
#[schema(not_null, index_type = "text", comment = "User name")]
#[schema(not_null, comment = "User name")]
name: String,
#[schema(
auto_initialized,
Expand All @@ -32,7 +32,6 @@ pub struct User {
comment = "User status"
)]
status: String,
#[schema(index_type = "text")]
description: String,

// Info fields.
Expand All @@ -42,10 +41,10 @@ pub struct User {
not_null,
unique,
write_only,
comment = "User account",
index_type = "hash",
min_length = 4,
max_length = 16
max_length = 16,
comment = "User account"
)]
account: String,
#[schema(not_null, write_only, comment = "User password")]
Expand All @@ -61,8 +60,8 @@ pub struct User {
nonempty,
unique_items,
enum_values = "admin | worker | auditor",
comment = "User roles",
example = "admin, worker"
example = "admin, worker",
comment = "User roles"
)]
roles: Vec<String>,
#[schema(unique_items, reference = "Tag", comment = "User tags")]
Expand Down
14 changes: 7 additions & 7 deletions zino-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ dotenvy = "0.15.7"
etag = "4.0.0"
faster-hex = "0.9.0"
fluent = "0.16.0"
futures = "0.3.29"
futures = "0.3.30"
hkdf = "0.12.4"
hmac = "0.12.1"
http = "0.2.11"
Expand All @@ -203,7 +203,7 @@ ryu = "1.0.16"
serde_qs = "0.12.0"
serde_yaml = "0.9.29"
sha2 = "0.10.8"
sysinfo = "0.30.0"
sysinfo = "0.30.1"
task-local-extensions = "0.1.4"
toml = "0.8.8"
tracing = "0.1.40"
Expand Down Expand Up @@ -241,11 +241,11 @@ default-features = false
features = ["pure-rust"]

[dependencies.metrics]
version = "0.21.1"
version = "0.22.0"
optional = true

[dependencies.metrics-exporter-prometheus]
version = "0.12.2"
version = "0.13.0"
optional = true

[dependencies.minijinja]
Expand Down Expand Up @@ -360,14 +360,14 @@ features = [
]

[dev-dependencies]
anyhow = "1.0.76"
anyhow = "1.0.77"
arrayvec = "0.7.4"
base64-simd = "0.8.0"
criterion = "0.5.1"
data-encoding = "2.4.0"
libsm = "0.5.1"
libsm = "0.6.0"
sm3 = "0.4.2"
sonic-rs = "0.2.6"
sonic-rs = "0.3.0"
tinyvec = { version = "1.6.0", features = ["alloc"] }
uuid-simd = "0.8.0"

Expand Down
6 changes: 6 additions & 0 deletions zino-core/src/model/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ impl<'a> Column<'a> {
}
}

/// Returns `true` if the column supports fuzzy search.
#[inline]
pub fn fuzzy_search(&self) -> bool {
self.index_type() == Some("text") || self.has_attribute("fuzzy_search")
}

/// Returns the Avro schema.
pub fn schema(&self) -> Schema {
let type_name = self.type_name();
Expand Down
4 changes: 2 additions & 2 deletions zino-core/src/model/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ impl QueryContext {
pub fn emit_metrics(&self, action: impl Into<crate::SharedString>) {
metrics::histogram!(
"zino_model_query_duration_seconds",
self.start_time().elapsed().as_secs_f64(),
"action" => action.into(),
);
)
.record(self.start_time().elapsed().as_secs_f64());
}
}

Expand Down
2 changes: 1 addition & 1 deletion zino-core/src/orm/mysql.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ impl<'c> EncodeColumn<DatabaseDriver> for Column<'c> {
format!(r#"({field} = '') IS NOT FALSE"#)
} else if value == "not_null" {
format!(r#"({field} = '') IS FALSE"#)
} else if self.index_type() == Some("text") {
} else if self.fuzzy_search() {
if value.contains(',') {
value
.split(',')
Expand Down
2 changes: 1 addition & 1 deletion zino-core/src/orm/postgres.rs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ impl<'c> EncodeColumn<DatabaseDriver> for Column<'c> {
format!(r#"({field} = '') IS NOT FALSE"#)
} else if value == "not_null" {
format!(r#"({field} = '') IS FALSE"#)
} else if self.index_type() == Some("text") {
} else if self.fuzzy_search() {
if value.contains(',') {
value
.split(',')
Expand Down
5 changes: 3 additions & 2 deletions zino-core/src/orm/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,9 @@ pub trait Schema: 'static + Send + Sync + ModelHooks {
let entries = columns
.iter()
.map(|col| col.encode_value(map.get(col.name())))
.collect::<Vec<_>>();
values.push(format!("({})", entries.join(", ")));
.collect::<Vec<_>>()
.join(", ");
values.push(format!("({entries})"));
}

let table_name = Self::table_name();
Expand Down
2 changes: 1 addition & 1 deletion zino-core/src/orm/sqlite.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ impl<'c> EncodeColumn<DatabaseDriver> for Column<'c> {
format!(r#"({field} = '') IS NOT FALSE"#)
} else if value == "not_null" {
format!(r#"({field} = '') IS FALSE"#)
} else if self.index_type() == Some("text") {
} else if self.fuzzy_search() {
if value.contains(',') {
value
.split(',')
Expand Down
7 changes: 4 additions & 3 deletions zino-core/src/request/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,13 @@ pub trait RequestContext {
// Emit metrics.
#[cfg(feature = "metrics")]
{
metrics::increment_gauge!("zino_http_requests_in_flight", 1.0);
metrics::increment_counter!(
metrics::gauge!("zino_http_requests_in_flight").increment(1.0);
metrics::counter!(
"zino_http_requests_total",
"method" => self.request_method().as_ref().to_owned(),
"route" => self.matched_route().into_owned(),
);
)
.increment(1);
}

// Parse tracing headers.
Expand Down
15 changes: 6 additions & 9 deletions zino-core/src/response/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -607,19 +607,16 @@ impl<S: ResponseCode> Response<S> {
///
/// It should only be called when the response will finish.
pub fn response_time(&self) -> Duration {
let start_time = self.start_time;
let response_time = self.start_time.elapsed();
#[cfg(feature = "metrics")]
{
let labels = [("status_code", self.status_code().to_string())];
metrics::decrement_gauge!("zino_http_requests_in_flight", 1.0);
metrics::increment_counter!("zino_http_responses_total", &labels);
metrics::histogram!(
"zino_http_requests_duration_seconds",
start_time.elapsed().as_secs_f64(),
&labels,
);
metrics::gauge!("zino_http_requests_in_flight").decrement(1.0);
metrics::counter!("zino_http_responses_total", &labels).increment(1);
metrics::histogram!("zino_http_requests_duration_seconds", &labels,)
.record(response_time.as_secs_f64());
}
start_time.elapsed()
response_time
}

/// Sends a file to the client.
Expand Down
2 changes: 1 addition & 1 deletion zino-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ proc-macro = true
convert_case = "0.6.0"
proc-macro2 = "1.0.71"
quote = "1.0.33"
syn = "2.0.42"
syn = "2.0.43"

[dependencies.zino-core]
path = "../zino-core"
Expand Down
3 changes: 3 additions & 0 deletions zino-derive/docs/schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ Derives the [`Schema`](zino_core::orm::Schema) trait.
- **`#[schema(write_only)]`**: The `write_only` annotation is used to indicate that
the column is write-only and can not be seen by frontend users.

- **`#[schema(fuzzy_search)]`**: The `fuzzy_search` annotation is used to indicate that
the column supports fuzzy search.

- **`#[schema(on_delete = "action")]`**: The `on_delete` attribute sepcifies
the referential action for a foreign key when the parent table has a `DELETE` operation.
Supported values: **`cascade`** | **`restrict`**.
Expand Down
4 changes: 2 additions & 2 deletions zino-model/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct Application {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Application::model_namespace", index_type = "hash")]
Expand All @@ -36,7 +36,7 @@ pub struct Application {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand Down
4 changes: 2 additions & 2 deletions zino-model/src/collection/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct Collection {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Collection::model_namespace", index_type = "hash")]
Expand All @@ -38,7 +38,7 @@ pub struct Collection {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand Down
4 changes: 2 additions & 2 deletions zino-model/src/dataset/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub struct Dataset {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Dataset::model_namespace", index_type = "hash")]
Expand All @@ -38,7 +38,7 @@ pub struct Dataset {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand Down
4 changes: 2 additions & 2 deletions zino-model/src/group/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct Group {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Group::model_namespace", index_type = "hash")]
Expand All @@ -35,7 +35,7 @@ pub struct Group {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand Down
6 changes: 3 additions & 3 deletions zino-model/src/log/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct Log {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Log::model_namespace", index_type = "hash")]
Expand All @@ -34,7 +34,7 @@ pub struct Log {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand All @@ -47,7 +47,7 @@ pub struct Log {
topic: String,
#[schema(read_only)]
level: String,
#[schema(read_only, index_type = "text")]
#[schema(read_only)]
message: String,
#[schema(read_only)]
source: String,
Expand Down
6 changes: 3 additions & 3 deletions zino-model/src/message/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub struct Message {
// Basic fields.
#[schema(read_only)]
id: Uuid,
#[schema(not_null, index_type = "text")]
#[schema(not_null)]
name: String,
#[cfg(feature = "namespace")]
#[schema(default_value = "Message::model_namespace", index_type = "hash")]
Expand All @@ -35,7 +35,7 @@ pub struct Message {
visibility: String,
#[schema(default_value = "Active", index_type = "hash")]
status: String,
#[schema(index_type = "text")]

description: String,

// Info fields.
Expand All @@ -45,7 +45,7 @@ pub struct Message {
channel_id: Uuid, // resource.id, resource.namespace = "*:channel"
#[schema(reference = "Group")]
consumer_id: Option<Uuid>, // group.id
#[schema(index_type = "text")]

message: String,
#[cfg(feature = "tags")]
#[schema(reference = "Tag", index_type = "gin")]
Expand Down
Loading

0 comments on commit ad552d9

Please sign in to comment.