如何根据 key-value 对 objects 进行备用和分组

How to spare & group objects according key-value

我是新手,这是我的第一步。我想我从一个不简单的案例开始。

让我们看看: 我有 objects,有一个 ID (name) 和一个资源组 (rgs)。每个 object 可能是几个组的一部分。而真正需要的是得到组的交集。

重要的是要说 object 可能是几个组的一部分,这些组是 parent-child 组,我只需要得到 parent 组。 parent引擎盖很容易识别,因为它们共享前缀。

例如组 PROM_FD_ARCNA 包含 child 个组 PROM_FD_ARCNA_TGMPROM_FD_ARCNA_TGM_TGA。 child 组包含 object 本身。但是,只要能拿到object的情报,就完了

parent 个组是 PROM_FD_ARCNAPROM_JOB_ICMPPROM_JOB_WIN。也就是说,我需要得到属于那些组的交集的那些object。

JSON 文件如下所示:

[
    {
        "id_ci": "487006",
        "name": "LABTNSARWID625",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGM, PROM_FD_ARCNA_TGM_TGA"
    },
    {
        "id_ci": "5706",
        "name": "HCCQ2001",
        "id_ci_class": "host",
        "rgs": "PROM_JOB_ICMP"
    },
    {
        "id_ci": "9106",
        "name": "HCC02155",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_ICMP"
    },
    {
        "id_ci": "2306",
        "name": "VM00006",
        "id_ci_class": "host",
        "rgs": "PROM_FD_ARCNA, PROM_FD_ARCNA_TGA, PROM_JOB_WIN, PROM_JOB_WIN_TGA"
    }
]

如果我的解释不好,我需要这样的JSON:

PROM_FD_ARCNA, PROM_JOB_ICMP
{
"HCC02155"
}

PROM_FD_ARCNA, PROM_JOB_WIN 
{
"VM00006"
}

因为这些是交叉路口。


到目前为止,我试过这个:

jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_FD_ARCNA")) | .rgs = "PROM_FD_ARCNA"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json 
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_WIN")) | .rgs = "PROM_JOB_WIN"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json 
jq '[.[] | select(.id_ci_class == "host") | select (.rgs | startswith("PROM_JOB_ICMP")) | .rgs = "PROM_JOB_ICMP"] 
| group_by(.rgs) | map({"rgs": .[0].rgs, "Hosts": map(.name)}) '  ./prom_jobs.json >> Step0A.json

结果是:

[
  {
    "rgs": "PROM_FD_ARCNA",
    "Hosts": [
      "LABTNSARWID625",
      "HCC02155",
      "VM00006"
    ]
  }
]
[
  {
    "rgs": "PROM_JOB_WIN",
    "Hosts": [
      "VM00006"
    ]
  }
]
[
  {
    "rgs": "PROM_JOB_ICMP",
    "Hosts": [
      "HCCQ2001",
      "HCC02155"
    ]
  }
]

当然,完整的JSON很长,我需要尽可能轻量级地处理它。不知道我的开始是好是坏。

def to_set(s): reduce s as $_ ( {}; .[ $_ ] = true );

[ "PROM_FD_ARCNA", "PROM_JOB_ICMP", "PROM_JOB_WIN" ] as $roots |

map(
   {
      name,
      has_rg: to_set( .rgs | split( ", " )[] )
   }
) as $hosts |

[
   range( 0;    $roots | length ) as $i |  $roots[ $i ] as $g1 |
   range( $i+1; $roots | length ) as $j |  $roots[ $j ] as $g2 |
   {
      root_rgs: [ $g1, $g2 ],
      names: [
         $hosts[] |
         select( .has_rg[ $g1 ] and .has_rg[ $g2 ] ) |
         .name
      ]
   } |
   select( .names | length > 0 )
]

生产

[
  {
    "root_rgs": [
      "PROM_FD_ARCNA",
      "PROM_JOB_ICMP"
    ],
    "names": [
      "HCC02155"
    ]
  },
  {
    "root_rgs": [
      "PROM_FD_ARCNA",
      "PROM_JOB_WIN"
    ],
    "names": [
      "VM00006"
    ]
  }
]

Demo 在 jqplay