Skip to content

Commit

Permalink
convert fields output using single_valued_arrayref_to_scalar on 'q' q…
Browse files Browse the repository at this point in the history
…ueries
  • Loading branch information
mickeyn committed Nov 14, 2016
1 parent b47d34a commit 07aa12e
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 10 deletions.
21 changes: 12 additions & 9 deletions lib/MetaCPAN/Server/Controller.pm
Expand Up @@ -9,6 +9,7 @@ use List::MoreUtils ();
use Moose::Util ();
use Moose;
use MetaCPAN::Types qw( HashRef );
use MetaCPAN::Util qw( single_valued_arrayref_to_scalar );

BEGIN { extends 'Catalyst::Controller'; }

Expand Down Expand Up @@ -107,16 +108,18 @@ sub search : Path('_search') : ActionClass('Deserialize') {
}
delete $params->{callback};
eval {
$c->stash(
$self->model($c)->es->search(
{
index => $c->model('CPAN')->index,
type => $self->type,
body => $c->req->data || delete $params->{source},
%$params,
}
)
my $res = $self->model($c)->es->search(
{
index => $c->model('CPAN')->index,
type => $self->type,
body => $c->req->data || delete $params->{source},
%$params,
}
);
single_valued_arrayref_to_scalar( $_->{fields} )
for @{ $res->{hits}{hits} };
$c->stash($res);
1;
} or do { $self->internal_error( $c, $@ ) };
}

Expand Down
79 changes: 79 additions & 0 deletions lib/MetaCPAN/Util.pm
Expand Up @@ -8,12 +8,14 @@ use version;

use Digest::SHA1;
use Encode;
use Ref::Util qw( is_arrayref );
use Sub::Exporter -setup => {
exports => [
'author_dir', 'digest',
'extract_section', 'fix_pod',
'fix_version', 'numify_version',
'pod_lines', 'strip_pod',
'single_valued_arrayref_to_scalar'
]
};

Expand Down Expand Up @@ -125,6 +127,28 @@ sub pod_lines {
return \@return, $slop;
}

sub single_valued_arrayref_to_scalar {
my ( $array, $fields ) = @_;
my $is_arrayref = is_arrayref($array);

$array = [$array] unless $is_arrayref;

my $has_fields = defined $fields ? 1 : 0;
$fields ||= [];
my %fields_to_extract = map { $_ => 1 } @{$fields};
foreach my $hash ( @{$array} ) {
foreach my $field ( %{$hash} ) {
next if ( $has_fields and not $fields_to_extract{$field} );
my $value = $hash->{$field};

# We only operate when have an ArrayRef of one value
next unless is_arrayref($value) && scalar @{$value} == 1;
$hash->{$field} = $value->[0];
}
}
return $is_arrayref ? $array : @{$array};
}

1;

__END__
Expand All @@ -137,3 +161,58 @@ This function will digest the passed parameters to a 32 byte string and makes it
It consists of the characters A-Z, a-z, 0-9, - and _.
The digest is built using L<Digest::SHA1>.
=head2 single_valued_arrayref_to_scalar
Elasticsearch 1.x changed the data structure returned when fields are used.
For example before one could get a ArrayRef[HashRef[Str]] where now
that will come in the form of ArrayRef[HashRef[ArrayRef[Str]]]
This function reverses that behavior
By default it will do that for all fields that are a single valued array,
but one may pass in a list of fields to restrict this behavior only to the
fields given.
So this:
$self->single_valued_arrayref_to_scalar(
[
{
name => ['WhizzBang'],
provides => ['Food', 'Bar'],
},
...
]);
yields:
[
{
name => 'WhizzBang',
provides => ['Food', 'Bar'],
},
...
]
and this estrictive example):
$self->single_valued_arrayref_to_scalar(
[
{
name => ['WhizzBang'],
provides => ['Food'],
},
...
], ['name']);
yields:
[
{
name => 'WhizzBang',
provides => ['Food'],
},
...
]
=cut
2 changes: 1 addition & 1 deletion t/server/controller/search/reverse_dependencies.t
Expand Up @@ -124,7 +124,7 @@ test_psgi app, sub {

my $json = decode_json_ok($res);
is( $json->{hits}->{total}, 1, 'total is 1' );
is( $json->{hits}->{hits}->[0]->{fields}->{distribution}->[0],
is( $json->{hits}->{hits}->[0]->{fields}->{distribution},
'Multiple-Modules-RDeps-A', 'filter worked' );
}
};
Expand Down

0 comments on commit 07aa12e

Please sign in to comment.