jq

How to filter elements by values from another arrays


I have the following JSON data:

{
    "services": [
        {
            "name": "B1",
            "criticality": "BC"
        },
        {
            "name": "B2",
            "criticality": "BC"
        },
        {
            "name": "M1",
            "criticality": "MC"
        },
        {
            "name": "M2",
            "criticality": "MC"
        },
        {
            "name": "M3",
            "criticality": "MC"
        },
        {
            "name": "M4",
            "criticality": "MC"
        }
    ],
    "links": [
        {
            "from_name": "B1",
            "to_name": "M1"
        },
        {
            "from_name": "M1",
            "to_name": "M2"
        },
        {
            "from_name": "M2",
            "to_name": "B2"
        },
        {
            "from_name": "M1",
            "to_name": "M3"
        },
        {
            "from_name": "M4",
            "to_name": "M2"
        }
    ]
}

I want to find the services those have criticality==MC and depends from other services with criticality==MC.

Output may look like the following: service and its dependencies

{
  "M1": [
    "M2",
    "M3"
  ],
  "M4": [
    "M2"
  ]
}

(it could be an array instead of list)

How to do it?


When I dig into links, I lost information about services and vice versa:

.links[] as $in | .services.[] | select(.name == $in.from_name) | select(.criticality == "MC")

will produce:

{
  "name": "M1",
  "criticality": "MC"
}
{
  "name": "M2",
  "criticality": "MC"
}

But there is no information about .links.


Solution

  • My solution is:

    # find the MC services and put them into $mc
    [ .services[] | select(.criticality == "MC") | .name ] as $mc | 
    
    # filter links by having MC only in source and target
    [ .links[] | select(.from_name | IN($mc[])) | select(.to_name | IN($mc[])) ] |
    
    # group results by .from_name
    group_by(.from_name) | map({(.[0].from_name):map(.to_name)}) | add
    

    Check online: https://jqplay.org/s/AwFt0Ke7DLO