I have the following dictionary
grouped:
10000:
- {Id: 10001, Name: North_America, Parent_Id: 10000, Type: Country}
10001:
- {Id: 10011, Name: Maine, Parent_Id: 10001, Type: State}
- {Id: 10012, Name: Colorado, Parent_Id: 10001, Type: State}
- {Id: 10013, Name: Texas, Parent_Id: 10001, Type: State}
10011:
- {Id: 10101, Name: Augusta, Parent_Id: 10011, Type: City}
- {Id: 10102, Name: Portland, Parent_Id: 10011, Type: City}
10012:
- {Id: 10103, Name: Denver, Parent_Id: 10012, Type: City}
10013:
- {Id: 10104, Name: Austin, Parent_Id: 10013, Type: City}
- {Id: 10105, Name: Houston, Parent_Id: 10013, Type: City}
10101:
- {Id: 11001, Name: First_st, Parent_Id: 10101, Type: Street}
- {Id: 11002, Name: Second_st, Parent_Id: 10101, Type: Street}
10102:
- {Id: 11003, Name: First_st, Parent_Id: 10102, Type: Street}
- {Id: 11004, Name: Second_st, Parent_Id: 10102, Type: Street}
10104:
- {Id: 11005, Name: First_st, Parent_Id: 10104, Type: Street}
- {Id: 11006, Name: Second_st, Parent_Id: 10104, Type: Street}
If I'm given a string containing Country-State-City-Street
, eg North_America-Texas-Austin-First_st
, I want to
The end goal, if the search string "North_America-Texas-Austin-Third_st" is provided and it does not exist in the dict, it will be added
First step is to identify the required Key, I've attempted json_queries and selectattr to do this but none work
---
hosts: localhost
gather_facts: false
connection: local
vars:
target: "North_America-Colorado-Denver-First_st"
tasks:
- name: Get the id using json filter and jmespath query
set_fact:
group_id: "{{ grouped | json_query(ID_query) | map(attribute='key') }}"
vars:
ID_query: '[?[*].Name == `North-America`]'
- debug: var=group_id
- name: Get the id using selectattr
set_fact:
group_id2: "{{ grouped | dict2items | selectattr('Name', 'search', 'North_America') }}"
- debug: var=group_id2
Output from the first debug is an empty list
ok: [localhost] => {
"group_id": []
}
Output from the second debug says that the dict object has no attribute Name
Create a dictionary of ids
ids: "{{ dict(grouped.keys()|
zip(grouped.values()|
map('items2dict', key_name='Name', value_name='Id'))) }}"
gives
ids:
10000: {North_America: 10001}
10001: {Colorado: 10012, Maine: 10011, Texas: 10013}
10011: {Augusta: 10101, Portland: 10102}
10012: {Denver: 10103}
10013: {Austin: 10104, Houston: 10105}
10101: {First_st: 11001, Second_st: 11002}
10102: {First_st: 11003, Second_st: 11004}
10104: {First_st: 11005, Second_st: 11006}
Then, use it. For example
- debug:
msg: "{{ item }} [{{ target_ok }}] {{ target_id }}"
loop:
- North_America-Colorado-Denver-First_st
- North_America-Texas-Austin-First_st
- North_America-Texas-Austin-Third_st
vars:
f: "{{ item|split('-') }}"
country: "{{ ids.10000[f.0]|d('undef') }}"
state: "{{ ids[country|int][f.1]|d('undef') }}"
city: "{{ ids[state|int][f.2]|d('undef') }}"
street: "{{ ids[city|int][f.3]|d('undef') }}"
target_id: "{{ country }} {{ state }} {{ city }} {{ street }}"
target_ok: "{{ ('undef' in target_id.split())|ternary('KO', 'OK') }}"
gives abridged
msg: North_America-Colorado-Denver-First_st [KO] 10001 10012 10103 undef
msg: North_America-Texas-Austin-First_st [OK] 10001 10013 10104 11005
msg: North_America-Texas-Austin-Third_st [KO] 10001 10013 10104 undef