-
-
Notifications
You must be signed in to change notification settings - Fork 23
Search Keyword: parent
The [parent([STEPS])]
search keyword will walk back up the document hierarchy to the present node's parent node(s). This cannot be inverted.
[parent([STEPS])]
accepts up to one optional parameter, STEPS
, for which the default is 1. When used, this parameter specifies how many steps to walk up the data hierarchy from the present node(s). Attempts to step up beyond the document root will cause an error describing how many steps are possible versus how many were attempted. Passing a 0
for the STEPS
parameter will yield the present node.
To illustrate, the example commands below will use this sample data as parent-examples.yaml:
---
minerals:
silicates:
Opal:
mohs_hardness: [5.5,6]
specific_gravity: [2.06,2.23]
Tourmaline:
mohs_hardness: [7,7.5]
specific_gravity: [3,3.26]
non-silicates:
Azurite:
mohs_hardness: [3.5,4]
specific_gravity: [3.773,3.78]
Bismuth:
mohs_hardness: [2.25,2.25]
specific_gravity: [9.87]
Crocoite:
mohs_hardness: [2.5,3]
specific_gravity: [6,6]
Flourite:
mohs_hardness: [4,4]
specific_gravity: [3.175,3.184]
Rhodochrosite:
mohs_hardness: [3.5,4]
specific_gravity: [3.5,3.7]
"Rose Quartz":
mohs_hardness: [7,7]
specific_gravity: [2.6,2.7]
Uvarovite:
mohs_hardness: [6.5,7.5]
specific_gravity: [3.77,3.81]
The first parent of any node is its immediate predecessor node, excluding the document root which has no parent. There may be cases when you can target a particular node with your query for a match, but you really want a different property of its parent. For a rudimentary example, imagine performing a deep traversal by a mineral name, but what you're really after is whether or not it is a silicate, which is given by the name of the group it is assigned to. We can find the name using the [name()]
search keyword. Given how the sample data is organized, you could check for whether Opal is a silicate like so:
$ yaml-get --query='**.Opal[parent()][name()]' parent-examples.yaml
silicates
Opal is a silicate given the name of its first parent node.
What if you wanted the name of any minerals -- including all silicates and non-silicates -- with a Mohs Hardness over 7? We can see in the data that each mineral has a range of Mohs Hardness ratings, which we can compare using a search expression. We can also see that the name of each mineral is two levels higher than those ratings. So, this query will match the data we seek:
$ yaml-get --query='minerals.*.*.mohs_hardness[.>7][parent(2)][name()]' parent-examples.yaml
Tourmaline
Uvarovite
The query is agnostic to whether the matches are silicates or non-silicates. To wit, it matches one of each from the sample data.
How would you match minerals in the sample data for which the Mohs Hardness is between 4 and 5? You can use Collector Math to set the limits of your value range. To do so, collect all nodes greater than (or greather-than-or-equal-to, depending on your use-case) the lower limit of your range and subtract from the result those nodes that are greater than (or greather-than-or-equal-to, depending on your use-case) the upper limit.
$ yaml-get --query='minerals.*.*(([mohs_hardness[0]>=4])-([mohs_hardness[1]>5]))[name()]' parent-examples.yaml
Flourite
Of the available minerals, only Flourite has a Mohs Hardness between 4 and 5.