From 4d3a4df647c2bf44c8795a2e8197703e3bc5e621 Mon Sep 17 00:00:00 2001 From: Kyle Huynh Date: Wed, 4 May 2022 13:27:07 +0000 Subject: [PATCH] Seperated detection of dismax and field search Exact match: need to change full text field to String to be effective --- src/AdvancedSearchQuery.php | 108 ++++++++++++++++++-------------- src/AdvancedSearchQueryTerm.php | 14 +++++ 2 files changed, 74 insertions(+), 48 deletions(-) diff --git a/src/AdvancedSearchQuery.php b/src/AdvancedSearchQuery.php index 361ff16..4a83cc9 100644 --- a/src/AdvancedSearchQuery.php +++ b/src/AdvancedSearchQuery.php @@ -152,79 +152,91 @@ class AdvancedSearchQuery { // disable for Lucene and wildcard //$q[] = "{!boost b=boost_document}"; + // create a flag for active/inactive dismax + $isDismax = false; + // To support negative queries we must first bring in all documents. $q[] = $this->negativeQuery($terms) ? "*:*" : ""; $term = array_shift($terms); $q[] = $term->toSolrQuery($field_mapping); + + // set dismax is enabled if the field set to "all" + if ($term->getField() === "all") { + $isDismax = true; + } + + // for multiple conditions foreach ($terms as $term) { $q[] = $term->getConjunction(); $q[] = $term->toSolrQuery($field_mapping); + + // set dismax is enabled if the field set to "all" + if ($term->getField() === "all") { + $isDismax = true; + } } + $q = implode(' ', $q); - $case_insensitive_field = $this::getConfig(SettingsForm::SOLR_CASE_INSENSITIVE_FIELD_PREFIX, ''); + // Limit extra processing if Luncene Search is enable + if ($isDismax) { + $case_insensitive_field = $this::getConfig(SettingsForm::SOLR_CASE_INSENSITIVE_FIELD_PREFIX, ''); - /** @var Solarium\QueryType\Select\Query\Query $solarium_query */ - if ((strpos($q, "*") !== false || strpos($q, "?") !== false)) { - // if the query string contain '*', '?', OR is a single world, enable wildcard - $tmp = str_replace('"', "", trim($q)); - $query_fields = []; - foreach ($field_mapping as $key => $field) { - foreach ($field as $f => $item) { - // bs_ are boolean fields, do not work well with text search - if (substr($item, 0, 3) !== "bs_" && !in_array($item, ['score', 'random', 'boost_document']) - && ((strpos( $item, "sm_" ) === 0) || (strpos( $item, "tm_" ) === 0) || (strpos($item, "sort_ss_") === 0) || (strpos($item, "ts_") === 0) - || (strpos($item, "ss_") === 0) - )){ - array_push($query_fields, '('.$item. ':'. $tmp .')'); + /** @var Solarium\QueryType\Select\Query\Query $solarium_query */ + if ((strpos($q, "*") !== false || strpos($q, "?") !== false)) { + // if the query string contain '*', '?', OR is a single world, enable wildcard + $tmp = str_replace('"', "", trim($q)); + $query_fields = []; + foreach ($field_mapping as $key => $field) { + foreach ($field as $f => $item) { + // bs_ are boolean fields, do not work well with text search + if (substr($item, 0, 3) !== "bs_" && !in_array($item, ['score', 'random', 'boost_document']) + && ((strpos( $item, "sm_" ) === 0) || (strpos( $item, "tm_" ) === 0) || (strpos($item, "sort_ss_") === 0) || (strpos($item, "ts_") === 0) + || (strpos($item, "ss_") === 0) + )){ + array_push($query_fields, '('.$item. ':'. $tmp .')'); - // Add case insensitive fields in the query search fields - if ($case_insensitive_field !== '') { - $item_prefix = substr($item, 0, 3); - if ($item_prefix == "ss_" || $item_prefix == "sm_") { - $case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); - array_push($query_fields, '('.$case_insensitive_item. ':'. $tmp .')'); + // Add case insensitive fields in the query search fields + if ($case_insensitive_field !== '') { + $item_prefix = substr($item, 0, 3); + if ($item_prefix == "ss_" || $item_prefix == "sm_") { + $case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); + array_push($query_fields, '('.$case_insensitive_item. ':'. $tmp .')'); + } } - } + } } } + $q = implode(" ", array_unique($query_fields)); } - $q = implode(" ", array_unique($query_fields)); - } - else { + else { - // enable dismax search query option - /** @var Solarium\QueryType\Select\Query\Component\DisMax $dismax */ - $dismax = $solarium_query->getDisMax(); - $dismax->setQueryParser('dismax'); - $query_fields = []; - foreach ($field_mapping as $key => $field) { - foreach ($field as $f => $item) { - // bs_ are boolean fields, do not work well with text search - if (substr($item, 0, 3) !== "bs_") { - array_push($query_fields, $item); + // enable dismax search query option + /** @var Solarium\QueryType\Select\Query\Component\DisMax $dismax */ + $dismax = $solarium_query->getDisMax(); + $dismax->setQueryParser('dismax'); + $query_fields = []; + foreach ($field_mapping as $key => $field) { + foreach ($field as $f => $item) { + // bs_ are boolean fields, do not work well with text search + if (substr($item, 0, 3) !== "bs_") { + array_push($query_fields, $item); - if ($case_insensitive_field !== '') { - $item_prefix = substr($item, 0, 3); - if ($item_prefix == "ss_" || $item_prefix == "sm_") { - $case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); - array_push($query_fields, $case_insensitive_item); + if ($case_insensitive_field !== '') { + $item_prefix = substr($item, 0, 3); + if ($item_prefix == "ss_" || $item_prefix == "sm_") { + $case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); + array_push($query_fields, $case_insensitive_item); + } } } } } + $query_fields = implode(" ", array_unique($query_fields)); + $dismax->setQueryFields($query_fields); } - $query_fields = implode(" ", array_unique($query_fields)); - $dismax->setQueryFields($query_fields); - - // Looks like, somewhere in the previous steps, double quotes get added, we are removing them! - // ToDo: Look into where the original quotes are being added, and remove it there! - $q = trim($q); - $q = substr($q, 1); - $q = substr($q, 0, -1); } - $solarium_query->setQuery($q); } } diff --git a/src/AdvancedSearchQueryTerm.php b/src/AdvancedSearchQueryTerm.php index 65ef96c..a9de86f 100644 --- a/src/AdvancedSearchQueryTerm.php +++ b/src/AdvancedSearchQueryTerm.php @@ -284,6 +284,13 @@ class AdvancedSearchQueryTerm { $terms = []; $query_helper = \Drupal::service('solarium.query_helper'); $value = $query_helper->escapePhrase(trim($this->value)); + + // Added to handle exact matches keyword (surrounded by "") + if (preg_match('#^(\'|").+\1$#', $value) == 1) { + trim($value); + $value = str_replace('"\\', '', $value); + $value = str_replace('\\"', '', $value); + } if ($this->field === "all") { return $value; } @@ -295,5 +302,12 @@ class AdvancedSearchQueryTerm { $terms = implode(' ', $terms); return $this->include ? "($terms)" : "-($terms)"; } + /** + * Get Field search + */ + public function getField() { + return $this->field; + } + }