diff --git a/docs/filter.md b/docs/filter.md
index e022b98..f4d4be6 100644
--- a/docs/filter.md
+++ b/docs/filter.md
@@ -132,6 +132,18 @@ Evaluates to `true` if the value contains the text.
 { "key": { "$contains": "text" }}
 ```
 
+### `$any`
+Evaluates to `true` if any value matches the filter.
+```json
+{ "array": { "$any": { "$regex": "text" }}}
+```
+
+### `$all`
+Evaluates to `true` if all value matches the filter.
+```json
+{ "array": { "$all": { "$regex": "text" }}}
+```
+
 ## Misc Operators
 ### `$type`
 Evaluates to `true` if the value matches the specified type.
diff --git a/src/lib.rs b/src/lib.rs
index bfc3c02..22bdbaf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -197,7 +197,6 @@ pub fn try_matches(
     obj: &serde_json::Value,
 ) -> Result<bool, FilterError> {
     let filter = filter.as_object().unwrap();
-    let obj_map = obj.as_object().unwrap();
 
     // Handle the case where the filter has a single key, such as top level $and, $or, $not
     if filter.len() == 1 {
@@ -238,6 +237,25 @@ pub fn try_matches(
                 }
                 return Err(FilterError::InvalidFilter);
             }
+            "$contains" | "$in" => match obj {
+                serde_json::Value::String(str) => return Ok(str.contains(op_arg.as_str().unwrap())),
+                serde_json::Value::Array(values) => {
+                    return Ok(values.into_iter().any(|x| x == op_arg))
+                }
+                _ => {}
+            },
+            "$any" => {
+                let elem_filter = op_arg;
+                let list = obj.as_array().unwrap();
+                return Ok(list.into_iter().any(|x| matches(&elem_filter, x)));
+            }
+            "$all" => {
+                let elem_filter = json!({ "key": op_arg });
+                let list = obj.as_array().unwrap();
+                return Ok(!list
+                    .into_iter()
+                    .any(|x| !matches(&elem_filter, &json!({"key": x}))));
+            }
             _ => {
                 if op.starts_with('$') {
                     return Err(FilterError::UnknownOperator);
@@ -246,6 +264,7 @@ pub fn try_matches(
         }
     }
 
+    let obj_map = obj.as_object().unwrap();
     let mut conditions = vec![];
 
     for (key, val) in filter {
@@ -509,6 +528,18 @@ fn match_operator(
                     key,
                 );
             }
+            "$any" => {
+                let elem_filter = op_arg;
+                let list = raw_obj.get(key).unwrap().as_array().unwrap();
+                return Ok(list.into_iter().any(|x| matches(&elem_filter, x)));
+            }
+            "$all" => {
+                let elem_filter = json!({ "key": op_arg });
+                let list = raw_obj.get(key).unwrap().as_array().unwrap();
+                return Ok(!list
+                    .into_iter()
+                    .any(|x| !matches(&elem_filter, &json!({"key": x}))));
+            }
             _ => {
                 if op.starts_with('$') {
                     return Err(FilterError::UnknownOperator);
diff --git a/src/test.rs b/src/test.rs
index 941b2a8..c62ea59 100644
--- a/src/test.rs
+++ b/src/test.rs
@@ -3,6 +3,80 @@ mod tests {
     use crate::matches;
     use serde_json::json;
 
+    #[test]
+    fn array_element_match() {
+        assert!(matches(
+            &json!(
+                { "a": { "$contains": 3 }}
+            ),
+            &json!({ "a": [1,2,3,4]})
+        ));
+    }
+
+    #[test]
+    fn array_any_str() {
+        assert!(matches(
+            &json!(
+                { "a": { "$any": { "$contains": "world"} }}
+            ),
+            &json!({ "a": ["hello", "world"]})
+        ));
+    }
+
+    #[test]
+    fn array_any_sub() {
+        assert!(matches(
+            &json!(
+                { "a": { "$any": { "key": { "$contains": "world"} }}}
+            ),
+            &json!({ "a": [{ "key": "hello" }, {"key": "world"}]})
+        ));
+    }
+
+    #[test]
+    fn array_all_nested() {
+        assert!(!matches(
+            &json!(
+                { "key": { "$all": { "$gt": 10} }}
+            ),
+            &json!({ "key": [1,2,3,4,5]})
+        ));
+
+        assert!(matches(
+            &json!(
+                { "key": { "$all": { "$gt": 5} }}
+            ),
+            &json!({ "key": [6,7,8,9]})
+        ));
+    }
+
+    #[test]
+    fn array_all_direct() {
+        assert!(!matches(
+            &json!(
+                { "$all": { "$gt": 10} }
+            ),
+            &json!([1, 2, 3, 4, 5])
+        ));
+
+        assert!(matches(
+            &json!(
+                { "$all": { "$gt": 5} }
+            ),
+            &json!([6, 7, 8, 9])
+        ));
+    }
+
+    #[test]
+    fn array_any_direct() {
+        assert!(matches(
+            &json!(
+                { "$any": { "$contains": "world"} }
+            ),
+            &json!(["hello", "world"])
+        ));
+    }
+
     #[test]
     fn simple_mask() {
         assert!(matches(