From 16c299fe510a2f670ef64ba69f7b0fcd8b26f727 Mon Sep 17 00:00:00 2001 From: Blou Date: Wed, 23 Feb 2022 16:13:37 -0500 Subject: [PATCH] Bug 30173: The suppress limit breaks the OPAC adv search using OR When using the advanced search, it is possible to specify an OR (instead of the default AND) between the terms. In the OPAC, the system preferences OpacSuppression will add a limit to every search as "suppress:false". The problem is that the limit is simply added as "AND suppress:false" to the query, without validating if it makes sense. In the case of OR searches, it does not: (title:PuttingHarry) OR (title:HarryPutter) AND suppress:false will not produce the desired results. This fix (suggested by Kevin Carnes) makes sure to envelop the search terms before padding the AND suppress:false. To test: 1) Create two records with very distinctive titles, and prove that search one by title only return that one result. Same for the other. 2) Modify the OpacSuppression syspref to select "Hide" 3) Turn ON the ES tracing by editing koha-conf.xml and adding Stderr under elasticsearch. That will allow you to see the strings generated. 4) Go to the advsearch in OPAC, do an OR search for both titles. In your logs, you should see something like "query" : "(title:TITLE1) OR (title:TITLE2) AND suppress:false" and get only one result. 5) Apply the patch, run again, this time the log should show "query" : "((title:TITLE1) OR (title:TITLE2)) AND suppress:false" and return two results. --- Koha/SearchEngine/Elasticsearch/QueryBuilder.pm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm index 3e2cb1b784..2debaf37a2 100644 --- a/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm +++ b/Koha/SearchEngine/Elasticsearch/QueryBuilder.pm @@ -306,9 +306,16 @@ sub build_query_compat { # them into a structured ES query itself. Maybe later, though that'd be # more robust. $search_param_query_str = join( ' ', $self->_create_query_string(@search_params) ); + if ($search_param_query_str) { + $search_param_query_str = "($search_param_query_str)"; + } + my $search_param_limits_str = $self->_join_queries( $self->_convert_index_strings(@$limits) ); + if ($search_param_limits_str) { + $search_param_limits_str = "($search_param_limits_str)"; + } $query_str = join( ' AND ', $search_param_query_str || (), - $self->_join_queries( $self->_convert_index_strings(@$limits) ) || () ); + $search_param_limits_str || () ); # If there's no query on the left, let's remove the junk left behind $query_str =~ s/^ AND //; -- 2.25.1