diff --git a/SUMMARY.md b/SUMMARY.md
index 95a5734f..5d814fca 100644
--- a/SUMMARY.md
+++ b/SUMMARY.md
@@ -37,6 +37,7 @@
* [Eval](operators/eval.md)
* [File Operators](operators/file-operators.md)
* [Filter Operator](operators/filter.md)
+ * [First Operator](operators/first.md)
* [Flatten](operators/flatten.md)
* [Group By](operators/group-by.md)
* [Has](operators/has.md)
diff --git a/operators/first.md b/operators/first.md
new file mode 100644
index 00000000..ae0bd715
--- /dev/null
+++ b/operators/first.md
@@ -0,0 +1,319 @@
+# First
+
+Returns the first matching element in an array, or first matching value in a map.
+
+Can be given an expression to match with, otherwise will just return the first.
+
+## First matching element from array
+Given a sample.yml file of:
+```yaml
+- a: banana
+- a: cat
+- a: apple
+```
+then
+```bash
+yq 'first(.a == "cat")' sample.yml
+```
+will output
+```yaml
+a: cat
+```
+
+## First matching element from array with multiple matches
+Given a sample.yml file of:
+```yaml
+- a: banana
+- a: cat
+ b: firstCat
+- a: apple
+- a: cat
+ b: secondCat
+```
+then
+```bash
+yq 'first(.a == "cat")' sample.yml
+```
+will output
+```yaml
+a: cat
+b: firstCat
+```
+
+## First matching element from array with numeric condition
+Given a sample.yml file of:
+```yaml
+- a: 10
+- a: 100
+- a: 1
+- a: 101
+```
+then
+```bash
+yq 'first(.a > 50)' sample.yml
+```
+will output
+```yaml
+a: 100
+```
+
+## First matching element from array with boolean condition
+Given a sample.yml file of:
+```yaml
+- a: false
+- a: true
+ b: firstTrue
+- a: false
+- a: true
+ b: secondTrue
+```
+then
+```bash
+yq 'first(.a == true)' sample.yml
+```
+will output
+```yaml
+a: true
+b: firstTrue
+```
+
+## First matching element from array with null values
+Given a sample.yml file of:
+```yaml
+- a: null
+- a: cat
+- a: apple
+```
+then
+```bash
+yq 'first(.a != null)' sample.yml
+```
+will output
+```yaml
+a: cat
+```
+
+## First matching element from array with complex condition
+Given a sample.yml file of:
+```yaml
+- a: dog
+ b: 7
+- a: cat
+ b: 3
+- a: apple
+ b: 5
+```
+then
+```bash
+yq 'first(.b > 4 and .b < 6)' sample.yml
+```
+will output
+```yaml
+a: apple
+b: 5
+```
+
+## First matching element from map
+Given a sample.yml file of:
+```yaml
+x:
+ a: banana
+y:
+ a: cat
+z:
+ a: apple
+```
+then
+```bash
+yq 'first(.a == "cat")' sample.yml
+```
+will output
+```yaml
+a: cat
+```
+
+## First matching element from map with numeric condition
+Given a sample.yml file of:
+```yaml
+x:
+ a: 10
+y:
+ a: 100
+z:
+ a: 101
+```
+then
+```bash
+yq 'first(.a > 50)' sample.yml
+```
+will output
+```yaml
+a: 100
+```
+
+## First matching element from nested structure
+Given a sample.yml file of:
+```yaml
+items:
+ - a: banana
+ - a: cat
+ - a: apple
+```
+then
+```bash
+yq '.items | first(.a == "cat")' sample.yml
+```
+will output
+```yaml
+a: cat
+```
+
+## First matching element with no matches
+Given a sample.yml file of:
+```yaml
+- a: banana
+- a: cat
+- a: apple
+```
+then
+```bash
+yq 'first(.a == "dog")' sample.yml
+```
+will output
+```yaml
+```
+
+## First matching element from empty array
+Given a sample.yml file of:
+```yaml
+[]
+```
+then
+```bash
+yq 'first(.a == "cat")' sample.yml
+```
+will output
+```yaml
+```
+
+## First matching element from scalar node
+Given a sample.yml file of:
+```yaml
+hello
+```
+then
+```bash
+yq 'first(. == "hello")' sample.yml
+```
+will output
+```yaml
+```
+
+## First matching element from null node
+Given a sample.yml file of:
+```yaml
+null
+```
+then
+```bash
+yq 'first(. == "hello")' sample.yml
+```
+will output
+```yaml
+```
+
+## First matching element with string condition
+Given a sample.yml file of:
+```yaml
+- a: banana
+- a: cat
+- a: apple
+```
+then
+```bash
+yq 'first(.a | test("^c"))' sample.yml
+```
+will output
+```yaml
+a: cat
+```
+
+## First matching element with length condition
+Given a sample.yml file of:
+```yaml
+- a: hi
+- a: hello
+- a: world
+```
+then
+```bash
+yq 'first(.a | length > 4)' sample.yml
+```
+will output
+```yaml
+a: hello
+```
+
+## First matching element from array of strings
+Given a sample.yml file of:
+```yaml
+- banana
+- cat
+- apple
+```
+then
+```bash
+yq 'first(. == "cat")' sample.yml
+```
+will output
+```yaml
+cat
+```
+
+## First matching element from array of numbers
+Given a sample.yml file of:
+```yaml
+- 10
+- 100
+- 1
+```
+then
+```bash
+yq 'first(. > 50)' sample.yml
+```
+will output
+```yaml
+100
+```
+
+## First element with no filter from array
+Given a sample.yml file of:
+```yaml
+- 10
+- 100
+- 1
+```
+then
+```bash
+yq 'first' sample.yml
+```
+will output
+```yaml
+10
+```
+
+## First element with no filter from array of maps
+Given a sample.yml file of:
+```yaml
+- a: 10
+- a: 100
+```
+then
+```bash
+yq 'first' sample.yml
+```
+will output
+```yaml
+a: 10
+```
+
diff --git a/operators/parent.md b/operators/parent.md
index 94fd3fa4..02375f87 100644
--- a/operators/parent.md
+++ b/operators/parent.md
@@ -56,6 +56,29 @@ will output
sam
```
+## Get parents
+Match all parents
+
+Given a sample.yml file of:
+```yaml
+a:
+ b:
+ c: cat
+```
+then
+```bash
+yq '.a.b.c | parents' sample.yml
+```
+will output
+```yaml
+- c: cat
+- b:
+ c: cat
+- a:
+ b:
+ c: cat
+```
+
## N-th parent
You can optionally supply the number of levels to go up for the parent, the default being 1.
diff --git a/usage/xml.md b/usage/xml.md
index 4238e971..c5bb6bc5 100644
--- a/usage/xml.md
+++ b/usage/xml.md
@@ -319,7 +319,10 @@ Defaults to true
Given a sample.xml file of:
```xml
-
+
```
then
@@ -329,13 +332,19 @@ yq --xml-keep-namespace=false '.' sample.xml
will output
```xml
-
+
```
instead of
```xml
-
+
```
## Parse xml: keep raw attribute namespace
@@ -344,7 +353,10 @@ Defaults to true
Given a sample.xml file of:
```xml
-
+
```
then
@@ -354,13 +366,19 @@ yq --xml-raw-token=false '.' sample.xml
will output
```xml
-
+
+ baz
+ foobar
+
```
instead of
```xml
-
+
```
## Encode xml: simple