Skip to content

Commit

Permalink
author: top_uploaders: move ES query to new API endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
mickeyn committed Nov 20, 2016
1 parent 02e94cc commit 0ffc711
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 54 deletions.
39 changes: 39 additions & 0 deletions lib/MetaCPAN/Document/Release.pm
Expand Up @@ -5,6 +5,7 @@ use warnings;

use Moose;
use ElasticSearchX::Model::Document;
use DateTime;

use MetaCPAN::Types qw(:all);
use MetaCPAN::Util qw( numify_version );
Expand Down Expand Up @@ -364,5 +365,43 @@ sub find_github_based {
{ and => [ { term => { status => 'latest' } }, { or => $or } ] } );
}

sub top_uploaders {
my ( $self, $range ) = @_;

my $range_filter = {
range => {
date => {
from => $range eq 'all' ? 0 : DateTime->now->subtract(
$range eq 'weekly' ? 'weeks'
: $range eq 'monthly' ? 'months'
: $range eq 'yearly' ? 'years'
: 'weeks' => 1
)->truncate( to => 'day' )->iso8601
},
}
};

my $body = +{
query => { match_all => {} },
aggregations => {
author => {
aggregations => {
entries => {
terms => { field => 'author', size => 50 }
}
},
filter => $range_filter,
},
},
size => 0,
};

return $self->es->search({
index => $self->index->name,
type => 'release',
body => $body,
});
}

__PACKAGE__->meta->make_immutable;
1;
93 changes: 42 additions & 51 deletions lib/MetaCPAN/Server/Controller/Author.pm
Expand Up @@ -60,6 +60,24 @@ sub get : Path('') : Args(1) {
['The requested field(s) could not be found'] );
}

# endpoint: /author/by_id?id=<csv_author_ids>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub by_id : Path('by_id') : Args(0) {
my ( $self, $c ) = @_;
my @ids = map {uc} split /,/ => $c->req->parameters->{id};
$c->stash(
$self->es_by_key_vals( c => $c, key => 'pauseid', vals => \@ids )
);
}

# endpoint: /author/by_user?user=<csv_user_ids>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub by_user : Path('by_user') : Args(0) {
my ( $self, $c ) = @_;
my @users = split /,/ => $c->req->parameters->{user};
$c->stash(
$self->es_by_key_vals( c => $c, key => 'user', vals => \@users )
);
}

# endpoint: /author/search?key=<key>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub search : Path('search') : Args(0) {
my ( $self, $c ) = @_;
Expand Down Expand Up @@ -97,63 +115,36 @@ sub search : Path('search') : Args(0) {
};
};

$self->es_by_filter( c => $c, filter => $filter, cb => $cb );
}

# endpoint: /author/by_id?id=<csv_author_ids>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub by_id : Path('by_id') : Args(0) {
my ( $self, $c ) = @_;
my @ids = map {uc} split /,/ => $c->req->parameters->{id};
$self->es_by_key_vals( c => $c, key => 'pauseid', vals => \@ids );
}

# endpoint: /author/by_user?user=<csv_user_ids>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub by_user : Path('by_user') : Args(0) {
my ( $self, $c ) = @_;
my @users = split /,/ => $c->req->parameters->{user};
$self->es_by_key_vals( c => $c, key => 'user', vals => \@users );
$c->stash(
$self->es_by_filter( c => $c, filter => $filter, cb => $cb )
);
}

# endpoint: /author/top_uploaders?range=<range>[&fields=<csv_fields>][&sort=<csv_sort>][&size=N]
sub top_uploaders : Path('top_uploaders') : Args(0) {
my ( $self, $c ) = @_;
my $range = $c->req->parameters->{range};

my $range_filter = {
range => {
date => {
from => $range eq 'all' ? 0 : DateTime->now->subtract(
$range eq 'weekly' ? 'weeks'
: $range eq 'monthly' ? 'months'
: $range eq 'yearly' ? 'years'
: 'weeks' => 1
)->truncate( to => 'day' )->iso8601
},
}
my $range = $c->req->parameters->{range};
my $data = $c->model('CPAN::Release')->top_uploaders;
my $counts = +{
map { $_->{key} => $_->{doc_count} }
@{ $data->{aggregations}{author}{entries}{buckets} }
};

my $body = +{
query => { match_all => {} },
aggregations => {
author => {
aggregations => {
entries => {
terms => { field => 'author', size => 50 }
}
},
filter => $range_filter,
},
},
size => 0,
};

my $res = $c->model('CPAN::Release')->es->search({
index => $c->model('CPAN::Release')->index->name,
type => 'release',
body => $body,
});

# TODO
my $authors = $self->es_by_key_vals( c => $c, key => 'pauseid', vals => [keys %$counts] );
$c->stash(
{
authors => [
sort { $b->{releases} <=> $a->{releases} } map {
{
%{ $_->{_source} },
releases => $counts->{ $_->{_source}->{pauseid} }
}
} @{ $authors->{hits}{hits} }
],
took => $data->{took},
total => $data->{aggregations}{author}{total},
range => $range,
}
);
}

1;
4 changes: 3 additions & 1 deletion lib/MetaCPAN/Server/Controller/Favorite.pm
Expand Up @@ -31,7 +31,9 @@ sub find : Path('') : Args(2) {
sub by_user : Path('by_user') : Args(0) {
my ( $self, $c ) = @_;
my @users = split /,/ => $c->req->parameters->{user};
$self->es_by_key_vals( $c, 'user', \@users );
$c->stash(
$self->es_by_key_vals( $c, 'user', \@users )
);
}

__PACKAGE__->meta->make_immutable;
Expand Down
4 changes: 2 additions & 2 deletions lib/MetaCPAN/Server/Role/ES/Query.pm
Expand Up @@ -16,7 +16,7 @@ sub es_by_key_vals {
= +{
bool => { should => [ map +{ term => { $key => $_ } }, @vals ] }
};
$self->es_by_filter( c => $c, cb => $cb, filter => $filter );
return $self->es_by_filter( c => $c, cb => $cb, filter => $filter );
}

# queries by given filter
Expand Down Expand Up @@ -54,7 +54,7 @@ sub es_query_res {
$res = $res->size($size)->all;
$res = $cb->($res) if $cb and is_coderef($cb);

$c->stash($res);
return $res;
}

no Moose::Role;
Expand Down

0 comments on commit 0ffc711

Please sign in to comment.