Skip to content

Commit 0d31ee2

Browse files
committed
Move autocomplete queries from model to query module
1 parent e1d819a commit 0d31ee2

File tree

5 files changed

+170
-176
lines changed

5 files changed

+170
-176
lines changed

lib/MetaCPAN/Document/File/Set.pm

Lines changed: 2 additions & 171 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,11 @@ package MetaCPAN::Document::File::Set;
22

33
use Moose;
44

5-
use List::Util qw( max );
6-
use MetaCPAN::ESConfig qw( es_doc_path );
7-
use MetaCPAN::Query::Favorite ();
8-
use MetaCPAN::Query::File ();
9-
use MetaCPAN::Query::Release ();
10-
use MetaCPAN::Util qw( true false );
5+
use MetaCPAN::ESConfig qw( es_doc_path );
6+
use MetaCPAN::Util qw( true false );
117

128
extends 'ElasticSearchX::Model::Document::Set';
139

14-
has query_favorite => (
15-
is => 'ro',
16-
isa => 'MetaCPAN::Query::Favorite',
17-
lazy => 1,
18-
builder => '_build_query_favorite',
19-
handles => [qw< agg_by_distributions >],
20-
);
21-
22-
sub _build_query_favorite {
23-
my $self = shift;
24-
return MetaCPAN::Query::Favorite->new( es => $self->es );
25-
}
26-
27-
my @ROGUE_DISTRIBUTIONS = qw(
28-
Acme-DependOnEverything
29-
Bundle-Everything
30-
kurila
31-
perl-5.005_02+apache1.3.3+modperl
32-
perlbench
33-
perl_debug
34-
pod2texi
35-
spodcxx
36-
);
37-
3810
sub find {
3911
my ( $self, $module ) = @_;
4012

@@ -241,146 +213,5 @@ sub history {
241213
return $search->sort( [ { date => 'desc' } ] );
242214
}
243215

244-
sub _autocomplete {
245-
my ( $self, $query ) = @_;
246-
247-
my $search_size = 100;
248-
249-
my $sugg_res = $self->es->search(
250-
es_doc_path('file'),
251-
body => {
252-
suggest => {
253-
documentation => {
254-
text => $query,
255-
completion => {
256-
field => "suggest",
257-
size => $search_size,
258-
},
259-
},
260-
}
261-
},
262-
);
263-
264-
my %docs;
265-
for my $suggest ( @{ $sugg_res->{suggest}{documentation}[0]{options} } ) {
266-
$docs{ $suggest->{text} } = max grep {defined}
267-
( $docs{ $suggest->{text} }, $suggest->{score} );
268-
}
269-
270-
my $res = $self->es->search(
271-
es_doc_path('file'),
272-
body => {
273-
query => {
274-
bool => {
275-
must => [
276-
{ term => { indexed => true } },
277-
{ term => { authorized => true } },
278-
{ term => { status => 'latest' } },
279-
{ terms => { documentation => [ keys %docs ] } },
280-
],
281-
must_not => [
282-
{
283-
terms => { distribution => \@ROGUE_DISTRIBUTIONS }
284-
},
285-
],
286-
}
287-
},
288-
_source => [ qw(
289-
author
290-
date
291-
deprecated
292-
distribution
293-
documentation
294-
release
295-
) ],
296-
size => $search_size,
297-
},
298-
);
299-
300-
my $hits = $res->{hits}{hits};
301-
302-
my $fav_res
303-
= $self->agg_by_distributions(
304-
[ map $_->{_source}{distribution}, @$hits ] );
305-
306-
my $favs = $fav_res->{favorites};
307-
308-
my %valid = map {
309-
my $source = $_->{_source};
310-
(
311-
$source->{documentation} => {
312-
%$source, favorites => $favs->{ $source->{distribution} },
313-
}
314-
);
315-
} @{ $res->{hits}{hits} };
316-
317-
# remove any exact match, it will be added later
318-
my $exact = delete $valid{$query};
319-
320-
no warnings 'uninitialized';
321-
my @sorted = map { $valid{$_} }
322-
sort {
323-
my $a_data = $valid{$a};
324-
my $b_data = $valid{$b};
325-
$a_data->{deprecated} <=> $b_data->{deprecated}
326-
|| $b_data->{favorites} <=> $a_data->{favorites}
327-
|| $docs{$b} <=> $docs{$a}
328-
|| length($a) <=> length($b)
329-
|| $a cmp $b
330-
}
331-
keys %valid;
332-
333-
return {
334-
took => $sugg_res->{took} + $res->{took} + $fav_res->{took},
335-
suggestions => \@sorted,
336-
};
337-
}
338-
339-
sub autocomplete {
340-
my ( $self, @terms ) = @_;
341-
my $data = $self->_autocomplete( join ' ', @terms );
342-
343-
return {
344-
took => $data->{took},
345-
hits => {
346-
hits => [
347-
map {
348-
my $source = $_;
349-
+{
350-
fields => {
351-
map +( $_ => $source->{$_} ), qw(
352-
documentation
353-
release
354-
author
355-
distribution
356-
),
357-
},
358-
};
359-
} @{ $data->{suggestions} }
360-
],
361-
},
362-
};
363-
}
364-
365-
sub autocomplete_suggester {
366-
my ( $self, @terms ) = @_;
367-
my $data = $self->_autocomplete( join ' ', @terms );
368-
369-
return {
370-
took => $data->{took},
371-
suggestions => [
372-
map +{
373-
author => $_->{author},
374-
date => $_->{date},
375-
deprecated => $_->{deprecated},
376-
distribution => $_->{distribution},
377-
name => $_->{documentation},
378-
release => $_->{release},
379-
},
380-
@{ $data->{suggestions} }
381-
],
382-
};
383-
}
384-
385216
__PACKAGE__->meta->make_immutable;
386217
1;

lib/MetaCPAN/Query/Distribution.pm

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,20 @@ use MetaCPAN::Util qw(hit_total);
77

88
with 'MetaCPAN::Query::Role::Common';
99

10+
sub rogue_list {
11+
return qw(
12+
Acme-DependOnEverything
13+
Bundle-Everything
14+
kurila
15+
perl-5.005_02+apache1.3.3+modperl
16+
perlbench
17+
perl_debug
18+
perl_mlb
19+
pod2texi
20+
spodcxx
21+
);
22+
}
23+
1024
sub get_river_data_by_dist {
1125
my ( $self, $dist ) = @_;
1226

lib/MetaCPAN/Query/File.pm

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package MetaCPAN::Query::File;
22

33
use MetaCPAN::Moose;
44

5+
use List::Util qw( max );
56
use MetaCPAN::ESConfig qw( es_doc_path );
67
use MetaCPAN::Util qw( hit_total true false );
78

@@ -356,5 +357,150 @@ sub find_changes_files {
356357
return $file;
357358
}
358359

360+
sub _autocomplete {
361+
my ( $self, $query ) = @_;
362+
363+
my $search_size = 100;
364+
365+
my $sugg_res = $self->es->search(
366+
es_doc_path('file'),
367+
body => {
368+
suggest => {
369+
documentation => {
370+
text => $query,
371+
completion => {
372+
field => "suggest",
373+
size => $search_size,
374+
},
375+
},
376+
}
377+
},
378+
);
379+
380+
my %docs;
381+
for my $suggest ( @{ $sugg_res->{suggest}{documentation}[0]{options} } ) {
382+
$docs{ $suggest->{text} } = max grep {defined}
383+
( $docs{ $suggest->{text} }, $suggest->{score} );
384+
}
385+
386+
my $res = $self->es->search(
387+
es_doc_path('file'),
388+
body => {
389+
query => {
390+
bool => {
391+
must => [
392+
{ term => { indexed => true } },
393+
{ term => { authorized => true } },
394+
{ term => { status => 'latest' } },
395+
{ terms => { documentation => [ keys %docs ] } },
396+
],
397+
must_not => [
398+
{
399+
terms => {
400+
distribution => [
401+
$self->query->distribution->rogue_list
402+
]
403+
},
404+
},
405+
],
406+
}
407+
},
408+
_source => [ qw(
409+
author
410+
date
411+
deprecated
412+
distribution
413+
documentation
414+
release
415+
) ],
416+
size => $search_size,
417+
},
418+
);
419+
420+
my $hits = $res->{hits}{hits};
421+
422+
my $fav_res
423+
= $self->query->favorite->agg_by_distributions(
424+
[ map $_->{_source}{distribution}, @$hits ] );
425+
426+
my $favs = $fav_res->{favorites};
427+
428+
my %valid = map {
429+
my $source = $_->{_source};
430+
(
431+
$source->{documentation} => {
432+
%$source, favorites => $favs->{ $source->{distribution} },
433+
}
434+
);
435+
} @{ $res->{hits}{hits} };
436+
437+
# remove any exact match, it will be added later
438+
my $exact = delete $valid{$query};
439+
440+
no warnings 'uninitialized';
441+
my @sorted = map { $valid{$_} }
442+
sort {
443+
my $a_data = $valid{$a};
444+
my $b_data = $valid{$b};
445+
$a_data->{deprecated} <=> $b_data->{deprecated}
446+
|| $b_data->{favorites} <=> $a_data->{favorites}
447+
|| $docs{$b} <=> $docs{$a}
448+
|| length($a) <=> length($b)
449+
|| $a cmp $b
450+
}
451+
keys %valid;
452+
453+
return {
454+
took => $sugg_res->{took} + $res->{took} + $fav_res->{took},
455+
suggestions => \@sorted,
456+
};
457+
}
458+
459+
sub autocomplete {
460+
my ( $self, @terms ) = @_;
461+
my $data = $self->_autocomplete( join ' ', @terms );
462+
463+
return {
464+
took => $data->{took},
465+
hits => {
466+
hits => [
467+
map {
468+
my $source = $_;
469+
+{
470+
fields => {
471+
map +( $_ => $source->{$_} ), qw(
472+
documentation
473+
release
474+
author
475+
distribution
476+
),
477+
},
478+
};
479+
} @{ $data->{suggestions} }
480+
],
481+
},
482+
};
483+
}
484+
485+
sub autocomplete_suggester {
486+
my ( $self, @terms ) = @_;
487+
my $data = $self->_autocomplete( join ' ', @terms );
488+
489+
return {
490+
took => $data->{took},
491+
suggestions => [
492+
map +{
493+
author => $_->{author},
494+
date => $_->{date},
495+
deprecated => $_->{deprecated},
496+
distribution => $_->{distribution},
497+
name => $_->{documentation},
498+
release => $_->{release},
499+
},
500+
@{ $data->{suggestions} }
501+
],
502+
};
503+
}
504+
359505
__PACKAGE__->meta->make_immutable;
360506
1;

lib/MetaCPAN/Query/Search.pm

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,11 @@ sub build_query {
240240
}
241241
},
242242
],
243-
must_not =>
244-
[ { terms => { distribution => \@ROGUE_DISTRIBUTIONS } }, ],
243+
must_not => [ {
244+
terms => {
245+
distribution => [ $self->query->distribution->rogue_list ]
246+
}
247+
} ],
245248
must => [
246249
{
247250
bool => {

lib/MetaCPAN/Server/Controller/Search/Autocomplete.pm

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@ has '+type' => ( default => 'file' );
1414
sub get : Local : Path('') : Args(0) {
1515
my ( $self, $c ) = @_;
1616
$c->stash_or_detach(
17-
$self->model($c)->autocomplete( $c->req->param("q") ) );
17+
$c->model('ESQuery')->file->autocomplete( $c->req->param("q") ) );
1818
}
1919

2020
sub suggest : Local : Path('/suggest') : Args(0) {
2121
my ( $self, $c ) = @_;
22-
$c->stash_or_detach(
23-
$self->model($c)->autocomplete_suggester( $c->req->param("q") ) );
22+
$c->stash_or_detach( $c->model('ESQuery')
23+
->file->autocomplete_suggester( $c->req->param("q") ) );
2424
}
2525

2626
1;

0 commit comments

Comments
 (0)