]> git.deb.at Git - deb/packages.git/commitdiff
Packages::Search: Implement find_similar
authorFrank Lichtenheld <Frank Lichtenheld frank@lichtenheld.de>
Tue, 19 Jun 2007 02:22:45 +0000 (04:22 +0200)
committerFrank Lichtenheld <Frank Lichtenheld frank@lichtenheld.de>
Tue, 19 Jun 2007 02:22:45 +0000 (04:22 +0200)
Suggested by Enrico Zini.

For a given <package>, search for P<package>,
and then extract all the terms from the document
you find (you could also implement this part by
just looking up the description and applying the
same algorithms to it as in parse-packages, haven't
benchmarked that against each other).

With these terms then make a OR search. Ignore all
results <package>, since these are obvious ;)
The first few matches of the rest are usually
packages very similar to the one we started with.

lib/Packages/DoShow.pm
lib/Packages/Search.pm
templates/html/show.tmpl

index 1d21462878d4dbcf0e2a21f8e9d16c48000bcab8..611d65e4e2e1aedea02c7c5f366f078c07046acf 100644 (file)
@@ -120,6 +120,10 @@ sub do_show {
                        my $std = timediff($st1, $st0);
                        debug( "Data search and merging took ".timestr($std) ) if DEBUG;
 
+                       my @similar = find_similar( $pkg, "$DBDIR/xapian/",
+                                                   \%did2pkg );
+                       $contents{similar} = \@similar;
+
                        my $did = $page->get_newest( 'description' );
                        my $desc_md5 = $page->get_newest( 'description-md5' );
                        my @complete_tags = split(/, /, $page->get_newest( 'tag' ));
index 66b09441ba1ea72d84de6578e200a488971bf099..021f0fd46196fad9847ce57616e3ebd47da5f802 100644 (file)
@@ -58,6 +58,7 @@ our @ISA = qw( Exporter );
 our @EXPORT_OK = qw( read_entry read_entry_all read_entry_simple
                     read_src_entry read_src_entry_all find_binaries
                     do_names_search do_fulltext_search do_xapian_search
+                    find_similar
                     );
 our %EXPORT_TAGS = ( all => [ @EXPORT_OK ] );
 
@@ -240,6 +241,50 @@ sub do_xapian_search {
     }
 }
 
+sub find_similar {
+    my ($pkg, $db, $did2pkg) = @_;
+
+    my $db = Search::Xapian::Database->new( $db );
+    my $enq = $db->enquire( "P$pkg" );
+    debug( "Xapian Query was: ".$enq->get_query()->get_description(), 1) if DEBUG;
+    my $first_match = ($enq->matches(0,1))[0]->get_document();
+
+    my @terms;
+    my $term_it = $first_match->termlist_begin();
+    my $term_end = $first_match->termlist_end();
+
+    for ($term_it; $term_it ne $term_end; $term_it++) {
+       debug( "TERM: ".$term_it->get_termname(), 3);
+       push @terms, $term_it->get_termname();
+    }
+
+    my $rel_enq = $db->enquire( OP_OR, @terms );
+    debug( "Xapian Query was: ".$rel_enq->get_query()->get_description(), 1) if DEBUG;
+    my @rel_pkg = $rel_enq->matches(2,20);
+
+    use Data::Dumper;
+    debug(Dumper(\@rel_pkg),1);
+
+    my (@order, %tmp_results);
+    foreach my $match ( @rel_pkg ) {
+       my $id = $match->get_docid();
+       my $result = $did2pkg->{$id};
+
+       foreach (split /\000/o, $result) {
+           my @data = split /\s/, $_, 3;
+           debug ("Considering $data[0], arch = $data[2], relevance=".$match->get_percent(), 3) if DEBUG;
+           next if $data[0] eq $pkg;
+           unless ($tmp_results{$data[0]}++) {
+               push @order, $data[0];
+           }
+       }
+    }
+    undef $db;
+
+    debug ("ORDER: @order", 2) if DEBUG;
+    return @order[0..10];
+}
+
 sub find_binaries {
     my ($pkg, $archive, $suite, $src2bin) = @_;
 
index c4b1e904f1bd7df684e1fffbf8a2f2a8f00a4fa7..88274f4b81dc7bcc3819fe0eb55244edd86303e2 100644 (file)
 <p>Homepage: <a href="[% url | uri %]">[% url | html %]</a></p>
 [% END %]
 
+[% FOREACH sim IN similar %]
+       [% IF loop.first %]
+       <h3>Similar packages:</h3>
+       <ul>
+       [% END %]
+       <li><a href="/[% sim %]">[% sim %]</a></li>
+       [% '</ul>' IF loop.last %]
+[% END %]
+
 </div> <!-- end pmoreinfo -->
 [% END %]