Skip to content

Commit

Permalink
merge the expanded and collapsed into a single sendpoint
Browse files Browse the repository at this point in the history
Also merge the model methods into one entry point.

The frontend has previously munged the query, we take that munging now.
From that we determine if the results should be expanded or collapsed
based on the query itself.

For flexibility we now also all explicitly passing a flag indicating
whether we want collapsed results. Additionally we return in the data
whether the results are actually expanded or collapsed for inspection
which is especially useful when the backend decided what to do based on
the query.

Note that the result structure does not depend on collapsing or not,
just the data contained within it.
  • Loading branch information
jberger committed Nov 20, 2016
1 parent 3089322 commit 7eb0f85
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 25 deletions.
14 changes: 2 additions & 12 deletions lib/MetaCPAN/Server/Controller/Search/WebLike.pm
Expand Up @@ -19,22 +19,12 @@ sub simple : Chained('/search/index') : PathPart('simple') : Args(0) {
$c->stash( $model->run_query( file => $query ) );
}

sub expanded : Chained('/search/index') : PathPart('expanded') : Args(0) {
sub web : Chained('/search/index') : PathPart('web') : Args(0) {
my ( $self, $c ) = @_;
my $args = $c->req->params;

my $model = $c->model('Search');
my $results = $model->search_expanded( @{$args}{qw( q from size )} );

$c->stash($results);
}

sub collapsed : Chained('/search/index') : PathPart('collapsed') : Args(0) {
my ( $self, $c ) = @_;
my $args = $c->req->params;

my $model = $c->model('Search');
my $results = $model->search_collapsed( @{$args}{qw( q from size )} );
my $results = $model->search_web( @{$args}{qw( q from size collapsed )} );

$c->stash($results);
}
Expand Down
40 changes: 27 additions & 13 deletions lib/MetaCPAN/Server/Model/Search.pm
Expand Up @@ -21,11 +21,28 @@ sub _not_rogue {
return { not => { filter => { or => \@rogue_dists } } };
}

sub search_expanded {
my ( $self, $query, $from, $page_size ) = @_;
sub search_web {
my ( $self, $query, $from, $page_size, $collapsed ) = @_;
$page_size //= 20;
$from //= 0;

# munge the query
# these would be nicer if we had variable-length lookbehinds...
$query =~ s{(^|\s)author:([a-zA-Z]+)(?=\s|$)}{$1author:\U$2\E}g;
$query =~ s/(^|\s)dist(ribution)?:([\w-]+)(?=\s|$)/$1distribution:$3/g;
$query =~ s/(^|\s)module:(\w[\w:]*)(?=\s|$)/$1module.name.analyzed:$2/g;

my $results
= $collapsed // $query !~ /(distribution|module\.name\S*):/
? $self->_search_collapsed( $query, $from, $page_size )
: $self->_search_expanded( $query, $from, $page_size );

return $results;
}

sub _search_expanded {
my ( $self, $query, $from, $page_size ) = @_;

# When used for a distribution or module search, the limit is included in
# thl query and ES does the right thing.
my $es_query = $self->build_query(
Expand Down Expand Up @@ -57,15 +74,14 @@ sub search_expanded {
my $return = {
results => [ map { [$_] } @$results ],
total => $data->{hits}->{total},
took => sum( grep {defined} $data->{took}, $favorites->{took} )
took => sum( grep {defined} $data->{took}, $favorites->{took} ),
collapsed => \0,
};
return $return;
}

sub search_collapsed {
sub _search_collapsed {
my ( $self, $query, $from, $page_size ) = @_;
$page_size //= 20;
$from //= 0;

my $took = 0;
my $total;
Expand Down Expand Up @@ -151,9 +167,10 @@ sub search_collapsed {
$results = $self->_collapse_results($results);
my @ids = map { $_->[0]{id} } @$results;
$data = {
results => $results,
total => $total,
took => $took,
results => $results,
total => $total,
took => $took,
collapsed => \1,
};
my $descriptions = $self->search_descriptions(@ids);
$data->{took} += $descriptions->{took} || 0;
Expand All @@ -179,7 +196,6 @@ sub _collapse_results {
];
}

# was sub search {}
sub build_query {
my ( $self, $query, $params ) = @_;
$params //= {};
Expand Down Expand Up @@ -323,9 +339,7 @@ sub build_query {
);

# Ensure our requested fields are unique so that Elasticsearch doesn't
# return us the same value multiple times in an unexpected arrayref. For
# example, distribution is listed both above and in ->_search, which calls
# this function (->search) and gets merged with the query above.
# return us the same value multiple times in an unexpected arrayref.
$search->{fields} = [ uniq @{ $search->{fields} || [] } ];

return $search;
Expand Down

0 comments on commit 7eb0f85

Please sign in to comment.