Hashes of Arrays of Hashes of Arrays - perl

I have the following output from hash in perl:
$VAR1 = {
'ins_api' => {
'sid' => 'eoc',
'outputs' => {
'output' => [
{
'body' => {
'TABLE_interface' => {
'ROW_interface' => [
{
'vdc_lvl_in_pkts' => 17081772,
'vdc_lvl_in_avg_bits' => 3128,
'eth_autoneg' => 'on',
'eth_speed' => '1000 Mb/s',
'admin_state' => 'up',
'vdc_lvl_out_mcast' => '65247',
'state' => 'up',
'eth_mtu' => '1500',
'eth_hw_addr' => '78ba.f9ad.b248',
'eth_mdix' => 'off',
'interface' => 'mgmt0',
'eth_ip_addr' => '10.56.32.84',
'eth_bw' => 1000000,
'vdc_lvl_in_avg_pkts' => '3',
'vdc_lvl_out_bytes' => '3463952330',
'vdc_lvl_in_ucast' => '7653891',
'eth_ip_prefix' => '10.',
'eth_rxload' => '1',
'eth_txload' => '1',
'eth_reliability' => '255',
'eth_dly' => 10,
'vdc_lvl_in_mcast' => '8742911',
'eth_ip_mask' => 24,
'eth_bia_addr' => '78ba.f9ad.b248',
'eth_duplex' => 'full',
'vdc_lvl_out_pkts' => '8668507',
'vdc_lvl_out_avg_pkts' => '1',
'vdc_lvl_in_bcast' => '684970',
'vdc_lvl_out_avg_bits' => '1840',
'medium' => 'broadcast',
'vdc_lvl_out_bcast' => '5',
'vdc_lvl_out_ucast' => '8603255',
'eth_ethertype' => '0x0000',
'vdc_lvl_in_bytes' => '1985125644',
'eth_hw_desc' => 'GigabitEthernet'
},
{
'eth_babbles' => '0',
'eth_outbytes' => '7362149107971',
'eth_outucast' => '16348249961',
'eth_clear_counters' => 'never',
'eth_watchdog' => '0',
'eth_inpkts' => 8644872191,
'eth_inbytes' => '3415386845315',
'eth_out_flowctrl' => 'off',
'eth_bad_proto' => '0',
'eth_frame' => '0',
----- output omitted -------
},
What would be the best way to loop via ROW_interface array and print some of the elements? I am just trying to get the elements in the ROW_interface array.

my $ROW_Interfaces = $output->{body}{TABLE_interface}{ROW_interface};
for my $ROW_Interfaces (#$ROW_Interfaces) {
...
}
It seems there can be more than one output, so you'll have to locate the appropriate one similarly.

Similar to #ikegami's answer, but handles the multiple output entries. The if defined... is there as the structure isn't complete, and I wasn't sure if each entry had the same keys or not.
for my $output (#{ $VAR1->{ins_api}{outputs}{output} }){
for my $row_int (#{ $output->{body}{TABLE_interface}{ROW_interface} }){
print "$row_int->{eth_frame}\n" if exists $row_int->{eth_frame};
}
}

Related

how to perform merging of keys for common values in hash of hash in perl

I am working on a below hash of hashes in perl, wherein i have some values in
inner hash that are same for different key timestamps. Is there any way to merge the timestamp keys for similar values?
'Test Responder Data String' => {
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20' => 'xxy00171329968;data1',
'2018-01-27' => 'xxy00171329968;data1',
'2018-01-28' => 'xxy00171329968;data1'
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05' => 'aaa00175033226;response try',
'2018-01-08' => 'aaa00175033226;response try'
}
Expected Result:
'Test Responder Data String' => {
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20,2018-01-27,2018-01-28' => 'xxy00171329968;data1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05,2018-01-08' => 'aaa00175033226;response try'
}
my %h=(
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-20' => 'xxy00171329968;data1',
'2018-01-27' => 'xxy00171329968;data1',
'2018-01-28' => 'xxy00171329968;data1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05' => 'aaa00175033226;response try',
'2018-01-08' => 'aaa00175033226;response try'
);
my %t;
push #{ $t{ $h{$_} } }, $_ for keys %h;
my %result = map { join(",", #{$t{$_}}) => $_ } keys %t;
use Data::Dumper; print Dumper \%result;
output
$VAR1 = {
'2018-01-17' => 'rrr00175002256;try data',
'2018-01-05,2018-01-08' => 'aaa00175033226;response try',
'2018-01-26' => 'zzz00175002802;newData1',
'2018-01-04' => 'www00171510082;ResponderData',
'2018-01-27,2018-01-20,2018-01-28' => 'xxy00171329968;data1'
};

How to retrieve hash value from session in Perl

I am storing a hash in session. I am trying to retrieve the values from session, but is not successful. I want to loop through the hash value in session to generate a select box. Below is the session value
$VAR1 = {
'userDetails' => {
'roles' => [
{
'ln' => 'asdf',
'email' => 'test#example.com',
'session_id' => '14',
'is_active' => '0',
'role' => 'ndfbfd',
'facility_name' => 'jjjj',
'fn' => 'yyyyyy'
},
{
'ln' => 'asdf',
'email' => 'test#example.com',
'session_id' => '15',
'is_active' => '1',
'role' => 'ndfbfd',
'facility_name' => 'fbhsdf',
'fn' => 'yyyyyy'
},
{
'ln' => 'asdf',
'email' => 'test#example.com',
'session_id' => '16',
'is_active' => '1',
'role' => 'ndfbfd',
'facility_name' => 'mvsd',
'fn' => 'yyyyyy'
},
{
'ln' => 'asdf',
'email' => 'test#example.com',
'session_id' => '17',
'is_active' => '1',
'role' => 'bdfgre',
'facility_name' => 'jjjj',
'fn' => 'yyyyyy'
},
{
'ln' => 'asdf',
'email' => 'test#example.com',
'session_id' => '18',
'is_active' => '0',
'role' => 'gderere',
'facility_name' => 'jjjj',
'fn' => 'yyyyyy'
}
],
'ln' => 'asdf',
'logged_in' => '1',
'fn' => 'yyyyyy'
},
'logged_in' => '1',
'username' => 'test#example.com'
};
I am trying to retrieve the roles from the session
my %userDetails = $self->session('userDetails');
my %roles = $userDetails{'roles'};
foreach my $family ( keys %roles ) {
print "$family: { ";
for my $role ( keys %{ $HoH{$family} } ) {
print "$role=$HoH{$family}{$role} ";
}
print "}\n";
}
It is showing two errors.
Reference found where even-sized list expected.
Odd number of elements in hash assignment.
When I change the code my %userDetails = $self->session('userDetails'); to my %userDetails = \$self->session('userDetails'); I am getting the error
Odd number of elements in hash assignment.
Odd number of elements in hash assignment.
Just guessing blatantly
my %userDetails = %{$self->session('userDetails')};
my #roles = #{$userDetails{'roles'}};
require Data::Dumper;
foreach my $family ( #roles ) {
print Data::Dumper::Dumper($family);
}
In your example
'roles' => [
so this indicates that the value beneath the role attribute is an array reference.
$self->session('userDetails')
might be hash, or more probably a hash-reference. I guessed the later. So if you have a reference to an "element" you derefence it first. See perldoc perlref

Hash value overwrite due to similar keys?

I want to map data from a German data structure to an English one.
For that I use a hash which holds the German words as keys and the English ones as values ($mapping_table).
The data are stored in an array of hashes ($data). The keys are the German words which have to be replaced by English ones. The values are the data which shall stay unchanged.
To do the mapping I have written the following code:
my $mapping_table = {
'Exemplare' => 'copies',
'Seiten' => 'pages',
'Statushinweis' => 'status',
'Serie von' => 'number_of',
'ISBN/Barcode-Nr.' => 'ISBN_barcode',
'Status' => 'status',
};
my $data = [
{
'Exemplare' => '1',
'Seiten' => '0',
'Statushinweis' => 'Statushinweis',
'ISBN/Barcode-Nr.' => '3-551-01561-9',
'Serie von' => '4',
'Status' => 'Gesucht'
},
{
'Exemplare' => '4',
'Seiten' => '111',
'Statushinweis' => '',
'ISBN/Barcode-Nr.' => '3-551-01561-9',
'Serie von' => '4',
'Status' => 'Vorhanden'
}
];
my $mapped_data = [];
foreach my $issue ( #$data ) {
my %tmp_hash;
foreach my $key (sort keys %$mapping_table) {
$tmp_hash{$mapping_table->{$key}} = $issue->{$key};
}
push #$mapped_data, \%tmp_hash;
}
print Dumper $mapped_data;
The result of the dump surprises me a lot.
$VAR1 = [
{
'number_of' => '4',
'copies' => '1',
'status' => 'Statushinweis',
'ISBN_barcode' => '3-551-01561-9',
'pages' => '0'
},
{
'pages' => '111',
'ISBN_barcode' => '3-551-01561-9',
'status' => '',
'copies' => '4',
'number_of' => '4'
}
];
It can be seen that the values of the keys 'status' hold those of the keys 'Statushinweis' whereas these keys got completely lost.
I tried to figure out why this happens with the help of Google and the debugger but failed (maybe to obvious to be seen?).
Maybe I should mention that I work with strawberry perl 5.26.1 on Win7.
Any idea what I did wrong and how to fix it?
Thx in advance.
Your mapping table needs to support bi-directional mapping. Currently, you cannot map from "value" (the, well, value) to "Status" or "Statushinweis", because both keys have the same value. If you can choose your keys freely, rename one of them, for instance:
my $mapping_table = {
'Exemplare' => 'copies',
'Seiten' => 'pages',
'Statushinweis' => 'statushint', // <- change here
'Serie von' => 'number_of',
'ISBN/Barcode-Nr.' => 'ISBN_barcode',
'Status' => 'status',
};
my $data = [
{
'Exemplare' => '1',
'Seiten' => '0',
'Statushinweis' => 'Statushinweis',
'ISBN/Barcode-Nr.' => '3-551-01561-9',
'Serie von' => '4',
'Status' => 'Gesucht'
},
{
'Exemplare' => '4',
'Seiten' => '111',
'Statushinweis' => '',
'ISBN/Barcode-Nr.' => '3-551-01561-9',
'Serie von' => '4',
'Status' => 'Vorhanden'
}
];

ElasticSearch (search_context_missing_exception) with Search::ElasticSearch::Scroll

I'm using Search::Elasticsearch and Search::Elasticsearch::Scroll for search and scroll into my elasticsearch server.
In scrolling process, for some querys, I'm seeing the next errors while I'm scrolling the search results:
2016/03/22 11:03:38 - 265885 FATAL: [Daemon.pm][8221]: Something gone wrong, error $VAR1 = bless( {
'msg' => '[Missing] ** [http://localhost:9200]-[404] Not Found, called from sub Search::Elasticsearch::Scroll::next at searcher.pl line 92. With vars: {\'body\' => {\'hits\' => {\'hits\' => [],\'max_score\' => \'0\',\'total\' => 5215},\'timed_out\' => bless( do{\\(my $o = 0)}, \'JSON::XS::Boolean\' ),\'_shards\' => {\'failures\' => [{\'index\' => undef,\'reason\' => {\'reason\' => \'No search context found for id [4920053]\',\'type\' => \'search_context_missing_exception\'},\'shard\' => -1},{\'index\' => undef,\'reason\' => {\'reason\' => \'No search context found for id [5051485]\',\'type\' => \'search_context_missing_exception\'},\'shard\' => -1},{\'index\' => undef,\'reason\' => {\'reason\' => \'No search context found for id [4920059]\',\'type\' => \'search_context_missing_exception\'},\'shard\' => -1},{\'index\' => undef,\'reason\' => {\'reason\' => \'No search context found for id [5051496]\',\'type\' => \'search_context_missing_exception\'},\'shard\' => -1},{\'index\' => undef,\'reason\' => {\'reason\' => \'No search context found for id [5051500]\',\'type\' => \'search_context_missing_exception\'},\'shard\' => -1}],\'failed\' => 5,\'successful\' => 0,\'total\' => 5},\'_scroll_id\' => \'c2NhbjswOzE7dG90YWxfaGl0czo1MjE1Ow==\',\'took\' => 2},\'request\' => {\'serialize\' => \'std\',\'path\' => \'/_search/scroll\',\'ignore\' => [],\'mime_type\' => \'application/json\',\'body\' => \'c2Nhbjs1OzQ5MjAwNTM6bHExbENzRDVReEc0OV9UMUgzd3Vkdzs1MDUxNDg1OnJrQ3lsUkRKVHRxRWRWeURoOTB4WVE7NDkyMDA1OTpscTFsQ3NENVF4RzQ5X1QxSDN3dWR3OzUwNTE0OTY6cmtDeWxSREpUdHFFZFZ5RGg5MHhZUTs1MDUxNTAwOnJrQ3lsUkRKVHRxRWRWeURoOTB4WVE7MTt0b3RhbF9oaXRzOjUyMTU7\',\'qs\' => {\'scroll\' => \'1m\'},\'method\' => \'GET\'},\'status_code\' => 404}
',
'stack' => [
[
'searcher.pl',
92,
'Search::Elasticsearch::Scroll::next'
]
],
'text' => '[http://localhost:9200]-[404] Not Found',
'vars' => {
'body' => {
'hits' => {
'hits' => [],
'max_score' => '0',
'total' => 5215
},
'timed_out' => bless( do{\(my $o = 0)}, 'JSON::XS::Boolean' ),
'_shards' => {
'failures' => [
{
'index' => undef,
'reason' => {
'reason' => 'No search context found for id [4920053]',
'type' => 'search_context_missing_exception'
},
'shard' => -1
},
{
'index' => undef,
'reason' => {
'reason' => 'No search context found for id [5051485]',
'type' => 'search_context_missing_exception'
},
'shard' => -1
},
{
'index' => undef,
'reason' => {
'reason' => 'No search context found for id [4920059]',
'type' => 'search_context_missing_exception'
},
'shard' => -1
},
{
'index' => undef,
'reason' => {
'reason' => 'No search context found for id [5051496]',
'type' => 'search_context_missing_exception'
},
'shard' => -1
},
{
'index' => undef,
'reason' => {
'reason' => 'No search context found for id [5051500]',
'type' => 'search_context_missing_exception'
},
'shard' => -1
}
],
'failed' => 5,
'successful' => 0,
'total' => 5
},
'_scroll_id' => 'c2NhbjswOzE7dG90YWxfaGl0czo1MjE1Ow==',
'took' => 2
},
'request' => {
'serialize' => 'std',
'path' => '/_search/scroll',
'ignore' => [],
'mime_type' => 'application/json',
'body' => 'c2Nhbjs1OzQ5MjAwNTM6bHExbENzRDVReEc0OV9UMUgzd3Vkdzs1MDUxNDg1OnJrQ3lsUkRKVHRxRWRWeURoOTB4WVE7NDkyMDA1OTpscTFsQ3NENVF4RzQ5X1QxSDN3dWR3OzUwNTE0OTY6cmtDeWxSREpUdHFFZFZ5RGg5MHhZUTs1MDUxNTAwOnJrQ3lsUkRKVHRxRWRWeURoOTB4WVE7MTt0b3RhbF9oaXRzOjUyMTU7',
'qs' => {
'scroll' => '1m'
},
'method' => 'GET'
},
'status_code' => 404
},
'type' => 'Missing'
}, 'Search::Elasticsearch::Error::Missing' );
The code I'm using is the next one (simplified) :
# Retrieve scroll
my $scroll = $self->getScrollBySignature($item);
# Retrieve all affected documents ids
while (my #docs = $scroll->next(500)) {
# Do stuff with #docs
}
The function getScrollBySignature have the next code in order to call to elasticSearch
my $scroll = $self->{ELASTIC}->scroll_helper(
index => $self->{INDEXES},
search_type => 'scan',
ignore_unavailable => 1,
body => {
size => $self->{PAGINATION},
query => {
filtered => {
filter => {
bool => {
must => [{term => {signature_id => $item->{profileId}}}, {terms => {channel_type_id => $type}}]
}
}
}
}
}
);
As you can see, I'm doing the scroll without passing scroll parameter then as documentation says, the time that scroll is alive is 1 min.
The elasticSearch is a cluster of 3 servers, and the query that ends with that error retrieves a bit more than 5000 docs.
My first solution was to update the life time for scroll to 5 minutes and the error didn't appear.
The question is, as I understand every time I'm calling $scroll->next() the life time off scroll affected is upgraded 1m more, then how is possible to receive those context related errors?
I'm doing something in a bad manner?
Thank you all.
The first thing that comes to mind is that the timer is not updated. Have you checked this? You can do a query every 10 seconds for example and see if at the 6th query it gives you the error ...
Well, a good rule of thumb is inside a ->next() block, don't stay by iteration more than time that you've configured in scroll.
Between each call of ->next() you cannot stay more than that time configured. If you stay more, the scroll may be not be there and the error earch_context_missing_exception will appear.
My solution for this problem was inside next block only store data into array/hash structure and once the scroll process ended work with all data.
The solution of the question example:
# Retrieve scroll
my $scroll = $self->getScrollBySignature($item);
# Retrieve all affected documents ids
my #allDocs;
while (my #docs = $scroll->next(500)) {
push #allDocs, map {$_->{_id}} #docs
}
foreach (#allDocs) {
# Do stuff with doc
}

Perl Hash Array foreach issue

I have a response which is displayed through Data::Dumper - Dumper($cat_response->result->{'categories'})
$VAR1 = { 'literature' => '1120', 'law' => '1153', 'arts and crafts' => '1132', 'children' => '1141', 'hobbies' => '1133', 'economy' => '1166', 'jobs' => '1140', 'media' => '1144', 'music' => '1147', 'animals' => '1170', 'business' => '1119', 'diet' => '1122', 'travel reviews' => '1154', 'jewelry' => '1157', 'movies' => '1146', 'television' => '1125', 'politics' => '1168', 'internet' => '1139', 'history' => '1129', 'recipes' => '1156', 'press releases' => '1151', 'presents' => '1128', 'marketing' => '1143', 'translations' => '1162', 'fashion' => '1145', 'technology' => '1163', 'real estate' => '1138', 'computer' => '1173', 'automobile' => '1116', 'finances' => '1126', 'weddings' => '1134', 'games' => '1127', 'esoterism' => '1124', 'horoscopes' => '1135', 'shopping' => '1123', 'humor' => '1137', 'miscellaneous' => '1159', 'science' => '1167', 'programming' => '1152', 'languages' => '1161', 'beauty' => '1117', 'sports' => '1160', 'hotels' => '1136', 'plants' => '1149', 'education' => '1118', 'traveling' => '1155', 'health' => '1130', 'telecommunication' => '1164', 'environment' => '1171', 'software' => '1158', 'sweepstakes' => '1131', 'logistics' => '1142', 'home and family' => '1169', 'news' => '1148' };
To access it, I use:
my %categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%categories)) {
<option value="<% $categories{'$cat'} %>"><% $cat %></option>
}
However, the value of Dumper($cat) is: $VAR1 = 'HASH(0x7fe972641560)';
Did I miss something?
You missing use strict; use warnings; for one. (Well, either that, or you forgot to tell us that Perl told you about your problem.)
$cat_response->result->{'categories'} contains a reference to a hash. Makes no sense to assign that to a hash.
my $categories = $cat_response->result->{'categories'};
foreach my $cat (keys (%$categories)) {
<option value="<% $categories->{'$cat'} %>"><% $cat %></option>
}