#!/bin/env perl use strict; use warnings; use Data::Dumper; use MongoDB; use Try::Tiny; my $conn; # the connection can fail try { $conn = MongoDB::Connection->new; } catch { chomp( my $err = $_ ); $err =~ s/ at .*//; die "Unable to connect to the default MongoDB ($err)"; }; my $db = $conn->mydb; # shouldn't ever die because MongoDB will create it if it doesn't exist my $hosts = $db->hosts; # ditto $hosts->insert({host => "127.0.0.1", timestamp => [ qw( 20110101 20110202 20110303 ) ]}); $hosts->insert({host => "127.0.0.2", timestamp => [ qw( 20110101 20110202 20110303 ) ]}); $hosts->insert({host => "127.0.0.3", timestamp => [ qw( 20110707 20110808 20110909 ) ]}); $hosts->insert({host => "127.0.0.1", timestamp => [ qw( 20111010 20111111 20111212 ) ]}); $hosts->insert({host => "127.0.0.2", timestamp => [ qw( 20110404 20110505 20110606 ) ]}); my $all_hosts = $hosts->find; my $ts; while ( my $host = $all_hosts->next ) { push @{$ts->{$host->{host}}}, @{$host->{timestamp}}; } # add non-existant host just to try and get an exception $ts->{'127.0.0.4'} = [ qw( 20120606 ) ]; $all_hosts->reset; for my $host ( keys %$ts ) { print "Updating $host..."; my @new = @{ $ts->{$host} }; # I wasn't able to get it to die even when trying to update a non-existant record # $rc->{updatedExisting} will contain a true/false value but $rc->{err} is always undef # but I feel better trying to catch the croak my $rc; try { $rc = $hosts->update( { host => $host }, { '$set' => { timestamp => [ @new ] } }, { multiple => 1, safe => 1 } ); } catch { warn sprintf( "Couldn't update records for host %s, %s", $host, $_ ); }; print $rc->{updatedExisting} ? 'success' : 'failure', "\n"; } while ( my $host = $all_hosts->next ) { printf "%s => %s\n", $host->{host}, Dumper( $host->{timestamp} ); } $hosts->drop; $db->drop;