Skip to content

Commit e8cc25a

Browse files
committed
feat: added exclude_keyvals transform
1 parent 7ad9512 commit e8cc25a

File tree

3 files changed

+65
-2
lines changed

3 files changed

+65
-2
lines changed

aw-query/src/functions.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ pub fn fill_env(env: &mut VarEnv) {
6767
qfunctions::chunk_events_by_key,
6868
),
6969
);
70+
env.insert(
71+
"exclude_keyvals".to_string(),
72+
DataType::Function("exclude_keyvals".to_string(), qfunctions::exclude_keyvals),
73+
);
7074
env.insert(
7175
"filter_keyvals".to_string(),
7276
DataType::Function("filter_keyvals".to_string(), qfunctions::filter_keyvals),
@@ -466,6 +470,25 @@ mod qfunctions {
466470
Ok(DataType::List(filtered_tagged_events))
467471
}
468472

473+
pub fn exclude_keyvals(
474+
args: Vec<DataType>,
475+
_env: &VarEnv,
476+
_ds: &Datastore,
477+
) -> Result<DataType, QueryError> {
478+
// typecheck
479+
validate::args_length(&args, 3)?;
480+
let events = (&args[0]).try_into()?;
481+
let key: String = (&args[1]).try_into()?;
482+
let vals: Vec<_> = (&args[2]).try_into()?;
483+
484+
let mut filtered_events = aw_transform::exclude_keyvals(events, &key, &vals);
485+
let mut filtered_tagged_events = Vec::new();
486+
for event in filtered_events.drain(..) {
487+
filtered_tagged_events.push(DataType::Event(event));
488+
}
489+
Ok(DataType::List(filtered_tagged_events))
490+
}
491+
469492
pub fn filter_period_intersect(
470493
args: Vec<DataType>,
471494
_env: &VarEnv,

aw-transform/src/filter_keyvals.rs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,30 @@ pub fn filter_keyvals_regex(mut events: Vec<Event>, key: &str, regex: &Regex) ->
5050
filtered_events
5151
}
5252

53+
/// Drops events matching the specified key and value(s). Opposite of filter_keyvals.
54+
///
55+
/// # Example
56+
/// ```ignore
57+
/// key: a
58+
/// vals: [1,2]
59+
/// input: [a:1][a:2][a:3][b:4]
60+
/// output: [a:3][b:4]
61+
/// ```
62+
pub fn exclude_keyvals(mut events: Vec<Event>, key: &str, vals: &[Value]) -> Vec<Event> {
63+
let mut filtered_events = Vec::new();
64+
'events: for event in events.drain(..) {
65+
if let Some(v) = event.data.get(key) {
66+
for val in vals {
67+
if val == v {
68+
continue 'events;
69+
}
70+
}
71+
}
72+
filtered_events.push(event);
73+
}
74+
filtered_events
75+
}
76+
5377
#[cfg(test)]
5478
mod tests {
5579
use std::str::FromStr;
@@ -61,7 +85,7 @@ mod tests {
6185

6286
use aw_models::Event;
6387

64-
use super::{filter_keyvals, filter_keyvals_regex};
88+
use super::{exclude_keyvals, filter_keyvals, filter_keyvals_regex};
6589

6690
#[test]
6791
fn test_filter_keyvals() {
@@ -108,4 +132,20 @@ mod tests {
108132
let res = filter_keyvals_regex(events.clone(), "key3", &regex_value);
109133
assert_eq!(0, res.len());
110134
}
135+
136+
#[test]
137+
fn test_exclude_keyvals() {
138+
let e1 = Event {
139+
id: None,
140+
timestamp: DateTime::from_str("2000-01-01T00:00:00Z").unwrap(),
141+
duration: Duration::seconds(1),
142+
data: json_map! {"test": json!(1)},
143+
};
144+
let mut e2 = e1.clone();
145+
e2.data = json_map! {"test": json!(1), "test2": json!(2)};
146+
let mut e3 = e1.clone();
147+
e3.data = json_map! {"test": json!(2)};
148+
let res = exclude_keyvals(vec![e1.clone(), e2.clone(), e3], "test", &vec![json!(2)]);
149+
assert_eq!(vec![e1, e2], res);
150+
}
111151
}

aw-transform/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ mod sort;
3737
pub use sort::{sort_by_duration, sort_by_timestamp};
3838

3939
mod filter_keyvals;
40-
pub use filter_keyvals::{filter_keyvals, filter_keyvals_regex};
40+
pub use filter_keyvals::{exclude_keyvals, filter_keyvals, filter_keyvals_regex};
4141

4242
mod filter_period;
4343
pub use filter_period::filter_period_intersect;

0 commit comments

Comments
 (0)