扁平化和过滤 ansible 中的复杂结构 - dict 列表中的 dict

Posted

技术标签:

【中文标题】扁平化和过滤 ansible 中的复杂结构 - dict 列表中的 dict【英文标题】:Flattening and filtering a complex structure in ansible - dict of list of dict 【发布时间】:2018-07-07 18:08:13 【问题描述】:

我有以这种方式表示的数据:

 
    "key1": [
      "name": "some name1",
      "index": "some idx1"
    ,
    
      "name": "some name2",
      "index": "some idx2"
    ,
    
      "name": "some name3",
      "index": "some idx3"
    ],
    "key2": [
      "name": "some name4",
      "index": "some idx4"
    ,
    
      "name": "some name5",
      "index": "some idx5"
    ,
    
      "name": "some name6",
      "index": "some idx6"
    ]
    

我想将上面的内容转换为这个,它基本上是一个字典,其中包含索引列表的现有键。

 
      "key1": [some idx1, some idx2, some idx3],
      "key2": [some idx4, some idx5, some idx6]

我已经看到了几个使用 map、extract 和 combine 的示例,但还不能完全使其工作。然而,我能够使用 jinja 来做到这一点,代码如下。 我的问题是,完成上述任务的最佳方法是什么。关于这种事情,推荐的最佳实践是什么 - 有什么理由不应该使用 jinja2 完成更复杂的操作(鉴于我见过的一个衬里过于复杂,其他人可能难以理解out - 因此使脚本难以维护)。

这里是解决问题的代码,但同样,不确定是否是实现此目的的最佳方法:

- hosts: local
  tags: test1
  gather_facts: False
  vars:
    dict1:
      key1:
        -  name: some name1, index: some idx1 
        -  name: some name2, index: some idx2 
        -  name: some name3, index: some idx3 
      key2:
        -  name: some name4, index: some idx4 
        -  name: some name5, index: some idx5 
        -  name: some name6, index: some idx6 
  tasks:      
  - name: "dict of list of dict"
    set_fact:
      index_map: |
        % set map = dict() %
        % for k,v in dict1.iteritems() %
          % set x=map.__setitem__(k, []) %
          % for item in v %
            % set x= map[k].append(item.name) %
          % endfor %
        % endfor %
         map 
  - debug: 
      msg: " index_map "

为了扩展我试图解决的更多问题:给定一个“索引”,我想找到与之关联的键。我认为目标结构可以让我更容易地做到这一点。因此,索引列表的键字典或键索引的字典就足够了。

感谢您的建议..

【问题讨论】:

【参考方案1】:

Ansible 使用字典中的键的工具相当有限(请参阅this answer)。

但dictsort 过滤器有时会很方便,就像您的情况一样。 它将dict转换为列表,您可以使用json_query对其进行处理。

这是一个通过索引名称获取根键的任务:

- debug:
    msg: "key is ' list_with_keys | json_query(qry) ' for index  item "
  vars:
    list_with_keys: " dict1 | dictsort | to_json | from_json "
    qry: "[?contains(([1] | [].index),` item `)][] | [0]"
  with_items:
    - some idx5
    - some idx3

dict1 取自您的示例。

【讨论】:

以上是关于扁平化和过滤 ansible 中的复杂结构 - dict 列表中的 dict的主要内容,如果未能解决你的问题,请参考以下文章

JSON多层嵌套复杂结构数据扁平化处理转为行列数据

Ansible检查复杂字典中的密钥

使用 LINQ 的对象层次结构的深度优先扁平化集合

使用 MongoDB 中的文档属性过滤器获取嵌入数组中的扁平文档数组

网站结构分为哪几种的?扁平型结构和树型结构,他们的含义是啥?有啥区别和作用呢?

Ansible最佳实践之Playbook高级循环任务如何操作