Allow combined search to be optional per class
authorMike Rylander <mrylander@gmail.com>
Tue, 16 Apr 2013 19:08:10 +0000 (15:08 -0400)
committerBen Shum <bshum@biblio.org>
Thu, 18 Apr 2013 17:41:17 +0000 (13:41 -0400)
Relevance is thrown off for, in paticular, the keyword class when combined
search is used.  This is because the effect of an opaque blob of data, such
as the keyword|keyword index definition, is to applify the inclusion of spurious
(to the user) data in matching attempts.

This commit adds the ability to specify, per class, whether combined FTS should
be used, and turns this on for only the subject class by default.

Signed-off-by: Mike Rylander <mrylander@gmail.com>
Signed-off-by: Ben Shum <bshum@biblio.org>
Open-ILS/examples/fm_IDL.xml
Open-ILS/src/perlmods/lib/OpenILS/Application/Storage/Driver/Pg/QueryParser.pm
Open-ILS/src/sql/Pg/002.schema.config.sql
Open-ILS/src/sql/Pg/upgrade/XXXX.schema.optional_combined_search.sql [new file with mode: 0644]

index 1b7cee5..44f34a2 100644 (file)
@@ -2345,6 +2345,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
                        <field reporter:label="Label" name="label" reporter:datatype="text" oils_persist:i18n="true"/>
                        <field reporter:label="Buoyant?" name="buoyant" reporter:datatype="bool" />
                        <field reporter:label="Restrict?" name="restrict" reporter:datatype="bool" />
+                       <field reporter:label="Combined?" name="combined" reporter:datatype="bool" />
                        <field reporter:label="A Weight" name="a_weight" reporter:datatype="float" />
                        <field reporter:label="B Weight" name="b_weight" reporter:datatype="float" />
                        <field reporter:label="C Weight" name="c_weight" reporter:datatype="float" />
index f69755a..d350eda 100644 (file)
@@ -217,6 +217,7 @@ sub add_search_field_id_map {
     my $field = shift;
     my $id = shift;
     my $weight = shift;
+    my $combined = shift;
 
     $self->add_search_field( $class => $field );
     $self->search_field_id_map->{by_id}{$id} = { classname => $class, field => $field, weight => $weight };
@@ -300,6 +301,18 @@ sub search_class_weights {
     return $self->custom_data->{class_weights}->{$class};
 }
 
+sub search_class_combined {
+    my $self = shift;
+    my $class = shift;
+    my $c = shift;
+
+    $self->custom_data->{class_combined} ||= {};
+    # Note: This reverses the A-D order, putting D first, because that is how the call actually works in PG
+    $self->custom_data->{class_combined}->{$class} ||= 0;
+    $self->custom_data->{class_combined}->{$class} = 1 if $c && $c =~ /^(?:t|y|1)/i;
+    return $self->custom_data->{class_combined}->{$class};
+}
+
 sub class_ts_config {
     my $self = shift;
     my $class = shift;
@@ -425,12 +438,13 @@ sub initialize_filter_normalizers {
     }
 }
 
-sub initialize_class_weights {
+sub initialize_search_class_weights {
     my $self = shift;
     my $classes = shift;
 
     for my $search_class (@$classes) {
         __PACKAGE__->search_class_weights( $search_class->name, $search_class->a_weight, $search_class->b_weight, $search_class->c_weight, $search_class->d_weight );
+        __PACKAGE__->search_class_combined( $search_class->name, $search_class->combined );
     }
 }
 
@@ -839,13 +853,17 @@ sub flatten {
                 if ($node->dummy_count < @{$node->only_atoms} ) {
                     $with .= ",\n     " if $with;
                     $with .= "${talias}_xq AS (SELECT ". $node->tsquery ." AS tsq,". $node->tsquery_rank ." AS tsq_rank )";
-                    $from .= "\n" . ${spc} x 6 . "JOIN $ctable AS com ON (com.record = fe.source";
-                    if (@field_ids) {
-                        $from .= " AND com.metabib_field IN (" . join(',',@field_ids) . "))";
+                    if ($node->combined_search) {
+                        $from .= "\n" . ${spc} x 6 . "JOIN $ctable AS com ON (com.record = fe.source";
+                        if (@field_ids) {
+                            $from .= " AND com.metabib_field IN (" . join(',',@field_ids) . "))";
+                        } else {
+                            $from .= " AND com.metabib_field IS NULL)";
+                        }
+                        $from .= "\n" . ${spc} x 6 . "JOIN ${talias}_xq ON (com.index_vector @@ ${talias}_xq.tsq)";
                     } else {
-                        $from .= " AND com.metabib_field IS NULL)";
+                        $from .= "\n" . ${spc} x 6 . "JOIN ${talias}_xq ON (fe.index_vector @@ ${talias}_xq.tsq)";
                     }
-                    $from .= "\n" . ${spc} x 6 . "JOIN ${talias}_xq ON (com.index_vector @@ ${talias}_xq.tsq)";
                 } else {
                     $from .= "\n" . ${spc} x 6 . ", (SELECT NULL::tsquery AS tsq, NULL:tsquery AS tsq_rank ) AS ${talias}_xq";
                 }
@@ -1324,6 +1342,11 @@ sub combined_table {
     return $self->combined_table( 'metabib.combined_' . $self->classname . '_field_entry' );
 }
 
+sub combined_search {
+    my $self = shift;
+    return $self->plan->QueryParser->search_class_combined($self->classname);
+}
+
 sub table_alias {
     my $self = shift;
     my $table_alias = shift;
index 946ac79..f10ad3d 100644 (file)
@@ -174,6 +174,7 @@ CREATE TABLE config.metabib_class (
     label    TEXT    NOT NULL UNIQUE,
     buoyant  BOOL    DEFAULT FALSE NOT NULL,
     restrict BOOL    DEFAULT FALSE NOT NULL,
+    combined BOOL    DEFAULT FALSE NOT NULL,
     a_weight NUMERIC  DEFAULT 1.0 NOT NULL,
     b_weight NUMERIC  DEFAULT 0.4 NOT NULL,
     c_weight NUMERIC  DEFAULT 0.2 NOT NULL,
diff --git a/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.optional_combined_search.sql b/Open-ILS/src/sql/Pg/upgrade/XXXX.schema.optional_combined_search.sql
new file mode 100644 (file)
index 0000000..2cab404
--- /dev/null
@@ -0,0 +1,4 @@
+
+ALTER TABLE config.metabib_class ADD COLUMN combined BOOL NOT NULL DEFAULT FALSE;
+UPDATE config.metabib_class SET combined = TRUE WHERE name = 'subject';
+