title: How to recursively search a list of dictionaries of lists containing an element of interest using Ansible/jq/json?
body: <p>I have an Ansible playbook(version 2.9), which initially displays the available block devices using lsblk command.
  The playbook is</p>
  <pre><code>- hosts: localhost
    tasks:
    - name: define variable
      shell: lsblk -oMOUNTPOINT,NAME  --json
      register: lsblk_output
    - debug:
        msg: &quot;{{ lsblk_output.stdout }}&quot;
  </code></pre>
  <p>The output of the lsblk command with JSON format, lsblk -oMOUNTPOINT,NAME  --json is</p>
  <pre><code>ok: [localhost] =&gt; {
      &quot;msg&quot;: {
          &quot;blockdevices&quot;: [
              {
                  &quot;mountpoint&quot;: &quot;/snap/core18/2246&quot;,
                  &quot;name&quot;: &quot;loop0&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/core18/2253&quot;,
                  &quot;name&quot;: &quot;loop1&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/core20/1169&quot;,
                  &quot;name&quot;: &quot;loop2&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/lxd/21803&quot;,
                  &quot;name&quot;: &quot;loop3&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/core20/1242&quot;,
                  &quot;name&quot;: &quot;loop4&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/lxd/21835&quot;,
                  &quot;name&quot;: &quot;loop5&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/snapd/14066&quot;,
                  &quot;name&quot;: &quot;loop6&quot;
              },
              {
                  &quot;mountpoint&quot;: &quot;/snap/snapd/13640&quot;,
                  &quot;name&quot;: &quot;loop7&quot;
              },
              {
                  &quot;children&quot;: [
                      {
                          &quot;mountpoint&quot;: &quot;/boot/efi&quot;,
                          &quot;name&quot;: &quot;sda1&quot;
                      },
                      {
                          &quot;mountpoint&quot;: &quot;/boot&quot;,
                          &quot;name&quot;: &quot;sda2&quot;
                      },
                      {
                          &quot;children&quot;: [
                              {
                                  &quot;children&quot;: [
                                      {
                                          &quot;mountpoint&quot;: &quot;/&quot;,
                                          &quot;name&quot;: &quot;ubuntu--vg-ubuntu--lv&quot;
                                      },
                                      {
                                          &quot;mountpoint&quot;: null,
                                          &quot;name&quot;: &quot;ubuntu--vg-clean&quot;
                                      }
                                  ],
                                  &quot;mountpoint&quot;: null,
                                  &quot;name&quot;: &quot;ubuntu--vg-ubuntu--lv-real&quot;
                              },
                              {
                                  &quot;children&quot;: [
                                      {
                                          &quot;mountpoint&quot;: null,
                                          &quot;name&quot;: &quot;ubuntu--vg-clean&quot;
                                      }
                                  ],
                                  &quot;mountpoint&quot;: null,
                                  &quot;name&quot;: &quot;ubuntu--vg-clean-cow&quot;
                              }
                          ],
                          &quot;mountpoint&quot;: null,
                          &quot;name&quot;: &quot;sda3&quot;
                      }
                  ],
                  &quot;mountpoint&quot;: null,
                  &quot;name&quot;: &quot;sda&quot;
              },
              {
                  &quot;children&quot;: [
                      {
                          &quot;mountpoint&quot;: null,
                          &quot;name&quot;: &quot;datavg-datavol1&quot;
                      }
                  ],
                  &quot;mountpoint&quot;: null,
                  &quot;name&quot;: &quot;sdb&quot;
              }
          ]
      }
  }
  </code></pre>
  <p>If I modify the above shell command to lsblk -oMOUNTPOINT,NAME  --json | jq '.blockdevices[] | select(.mountpoint == null) | .name'</p>
  <p>The output is</p>
  <pre><code>TASK [debug] *************************************************************************************************************************************************************
  ok: [localhost] =&gt; {
      &quot;msg&quot;: &quot;\&quot;sda\&quot;\n\&quot;sdb\&quot;&quot;
  }
  </code></pre>
  <p>But, I need only one drive name based on the fact that the drive contains the &quot;mountpoint&quot;: &quot;/&quot;. The expected output is sda. How else can I modify the above shell command, so that a recursive search is carried out and I get the desired output?</p>
  <p><strong>UPDATE</strong>
  I kept playing around and eventually for this role,</p>
  <pre><code>  - name: task22
      debug:
        msg: &quot;{{ jsonym.blockdevices }}&quot;
    - debug:
        msg: &quot;{{ ((jsonym.blockdevices) | flatten) | json_query(query) | list }} &quot;
  
      vars:
              query: &quot;[].children.{na:jsonym.name, mp: [?mountpoint == '/boot'].name }&quot;
  </code></pre>
  <p>The output is
  TASK [debug] ****************************************************************************************</p>
  <pre><code>ok: [localhost] =&gt;
    msg:
    - mp:
      - sda2
      na: null
    - mp: []
      na: null
  </code></pre>
  <p>Still not able to get the expected output.</p>