From d8a87ce0dadd810880f28a5a5ef2e15438db53c1 Mon Sep 17 00:00:00 2001 From: Kyle Huynh Date: Tue, 31 Jan 2023 11:20:28 -0500 Subject: [PATCH] Enabled edismax for field search as well Change wording in configiration view --- src/AdvancedSearchQuery.php | 85 +++++++++++++++++++++------------ src/AdvancedSearchQueryTerm.php | 31 +++++++++++- src/Form/AdvancedSearchForm.php | 24 +++++++--- src/Form/SettingsForm.php | 47 ++++++++++-------- 4 files changed, 128 insertions(+), 59 deletions(-) diff --git a/src/AdvancedSearchQuery.php b/src/AdvancedSearchQuery.php index 9ee3339..3ddc14e 100644 --- a/src/AdvancedSearchQuery.php +++ b/src/AdvancedSearchQuery.php @@ -154,57 +154,73 @@ class AdvancedSearchQuery { // create a flag for active/inactive dismax $isDismax = false; + $isSearchAllFields = false; + $fields_list = []; + + $config = \Drupal::config(SettingsForm::CONFIG_NAME); + $isDismax = $config->get(SettingsForm::EDISMAX_SEARCH_FLAG); // 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" + // new + $fields_list[] = $term->toSolrFields($field_mapping); + + // set edismax is enabled if the field set to "all" if ($term->getField() === "all") { - $isDismax = true; - } + $isSearchAllFields = true; + } + // for multiple conditions foreach ($terms as $term) { $q[] = $term->getConjunction(); $q[] = $term->toSolrQuery($field_mapping); + // new + $fields_list[] = $term->toSolrFields($field_mapping); + // set dismax is enabled if the field set to "all" if ($term->getField() === "all") { - $isDismax = true; + $isSearchAllFields = true; + } + } - $q = implode(' ', $q); + // 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 .')'); + + if ($isSearchAllFields) { + 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 .')'); + } } - } + } } } } @@ -217,22 +233,29 @@ class AdvancedSearchQuery { $dismax = $solarium_query->getEDisMax(); $dismax->setQueryParser('edismax'); $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 ($isSearchAllFields) { + 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); + } } } } } } + else { + $query_fields = $fields_list; + + } $query_fields = implode(" ", array_unique($query_fields)); $dismax->setQueryFields($query_fields); } diff --git a/src/AdvancedSearchQueryTerm.php b/src/AdvancedSearchQueryTerm.php index 4cbd8f0..9d70776 100644 --- a/src/AdvancedSearchQueryTerm.php +++ b/src/AdvancedSearchQueryTerm.php @@ -3,7 +3,7 @@ namespace Drupal\advanced_search; use Drupal\advanced_search\Form\AdvancedSearchForm; - +use Drupal\advanced_search\Form\SettingsForm; /** * Defines a single search term. * @@ -285,7 +285,10 @@ class AdvancedSearchQueryTerm { $query_helper = \Drupal::service('solarium.query_helper'); $value = $query_helper->escapePhrase(trim($this->value)); - if ($this->field === "all") { + $config = \Drupal::config(SettingsForm::CONFIG_NAME); + $isDismax = $config->get(SettingsForm::EDISMAX_SEARCH_FLAG); + + if ($isDismax || $this->field === "all") { // Case 1: if keyword contains one word or a phrase if(strpos(trim($value), ' ') !== false) { @@ -352,6 +355,30 @@ class AdvancedSearchQueryTerm { $terms = implode(' ', $terms); return $this->include ? "($terms)" : "-($terms)"; } + + + /** + * Using the provided field mapping create a Solr Fields string. + * + * @param array $solr_field_mapping + * An array that maps search api fields to one or more solr fields. + * + * @return string + * The conjunction to use for this term conjunction. + */ + public function toSolrFields(array $solr_field_mapping) { + $terms = []; + $query_helper = \Drupal::service('solarium.query_helper'); + + if ($this->field !== "all") { + foreach ($solr_field_mapping[$this->field] as $field) { + $terms[] = "$field"; + } + } + $terms = implode(' ', $terms); + return $terms; + } + /** * Get Field search */ diff --git a/src/Form/AdvancedSearchForm.php b/src/Form/AdvancedSearchForm.php index 4316eed..5eb2166 100644 --- a/src/Form/AdvancedSearchForm.php +++ b/src/Form/AdvancedSearchForm.php @@ -103,14 +103,24 @@ class AdvancedSearchForm extends FormBase { return self::getConfig(SettingsForm::SEARCH_REMOVE_OPERATOR, self::DEFAULT_REMOVE_OP); } - /** - * Get if Lucene Search checkbox is enabled or disable + /** + * Get if Edismax Search checkbox is enabled or disable * * @return boolean * */ - public static function getLuceneSearch() { - return self::getConfig(SettingsForm::LUCENE_SEARCH_FLAG, 0); + public static function getSearchAllFields() { + return self::getConfig(SettingsForm::SEARCH_ALL_FIELDS_FLAG, 0); + } + + /** + * Get if Edismax Search checkbox is enabled or disable + * + * @return boolean + * + */ + public static function getEdismaxSearch() { + return self::getConfig(SettingsForm::EDISMAX_SEARCH_FLAG, 0); } /** @@ -119,8 +129,8 @@ class AdvancedSearchForm extends FormBase { * @return string * The character to use for removing an facet to the query. */ - public static function getLuceneSearchLabel() { - return self::getConfig(SettingsForm::LUCENE_SEARCH_LABEL, "All"); + public static function getEdismaxSearchLabel() { + return self::getConfig(SettingsForm::EDISMAX_SEARCH_LABEL, "All"); } /** @@ -263,7 +273,7 @@ class AdvancedSearchForm extends FormBase { ], ]; - $options = (self::getLuceneSearch()) ? ["all" => self::getLuceneSearchLabel()] + $this->fieldOptions($fields) : $this->fieldOptions($fields); + $options = (self::getEdismaxSearch() && self::getSearchAllFields()) ? ["all" => self::getEdismaxSearchLabel()] + $this->fieldOptions($fields) : $this->fieldOptions($fields); $term_default_values = $this->defaultTermValues($options); list($recursive, $term_values) = $this->processInput($form_state, $term_default_values); $i = 0; diff --git a/src/Form/SettingsForm.php b/src/Form/SettingsForm.php index 6ad8ff5..0761a21 100644 --- a/src/Form/SettingsForm.php +++ b/src/Form/SettingsForm.php @@ -23,8 +23,9 @@ class SettingsForm extends ConfigFormBase { const SEARCH_REMOVE_OPERATOR = 'search_remove_operator'; const FACET_TRUNCATE = 'facet_truncate'; const SOLR_CASE_INSENSITIVE_FIELD_PREFIX = "case_insensitive_solr_field_prefix"; - const LUCENE_SEARCH_FLAG = 'lucene_on_off'; - const LUCENE_SEARCH_LABEL = 'lucene_label'; + const EDISMAX_SEARCH_FLAG = 'lucene_on_off'; + const EDISMAX_SEARCH_LABEL = 'lucene_label'; + const SEARCH_ALL_FIELDS_FLAG = 'all_fields_on_off'; /** * Constructs a \Drupal\system\ConfigFormBase object. @@ -115,34 +116,42 @@ class SettingsForm extends ConfigFormBase { ], ]; - $form['lucene'] = [ + $form['edismax'] = [ '#type' => 'fieldset', - '#title' => $this->t(" Solr's Standard Query parser (also known as 'lucene')"), + '#title' => $this->t("Extended DisMax Query"), ]; - $form['lucene'][self::LUCENE_SEARCH_FLAG] = [ + $form['edismax'][self::EDISMAX_SEARCH_FLAG] = [ '#type' => 'checkbox', '#title' => $this - ->t('Enable Lucene Search.'), - '#default_value' => self::getConfig(self::LUCENE_SEARCH_FLAG, 0), + ->t('Enable Extended DisMax Query.'), + '#default_value' => self::getConfig(self::EDISMAX_SEARCH_FLAG, 0), '#ajax' => [ 'callback' => '::LuceneSearchEnableDisableCallback', - 'wrapper' => 'lucene-container', + 'wrapper' => 'edismax-container', 'effect' => 'fade', ], ]; - $form['lucene']['textfields_container'] = [ + $form['edismax']['textfields_container'] = [ '#type' => 'container', - '#attributes' => ['id' => 'lucene-container'], + '#attributes' => ['id' => 'edismax-container'], ]; - if (self::getConfig(self::LUCENE_SEARCH_FLAG, "All") === 1 - || $form_state->getValue(self::LUCENE_SEARCH_FLAG) === 1) { - $form['lucene']['textfields_container'][self::LUCENE_SEARCH_LABEL] = [ + + + if (self::getConfig(self::EDISMAX_SEARCH_FLAG, "All") === 1 + || $form_state->getValue(self::EDISMAX_SEARCH_FLAG) === 1) { + $form['edismax']['textfields_container'][self::SEARCH_ALL_FIELDS_FLAG] = [ + '#type' => 'checkbox', + '#title' => $this + ->t('Enable searching all fields'), + '#default_value' => self::getConfig(self::SEARCH_ALL_FIELDS_FLAG, 0), + ]; + $form['edismax']['textfields_container'][self::EDISMAX_SEARCH_LABEL] = [ '#type' => 'textfield', - '#title' => $this->t('Label'), + '#title' => $this->t('If enabled, set the label for the option of searching all fields'), '#description' => $this->t('This label will be appear in Search Terms dropdown of Advanced Search form block if Lucene Search is enabled.'), - '#default_value' => self::getConfig(self::LUCENE_SEARCH_LABEL, "All"), + '#default_value' => self::getConfig(self::EDISMAX_SEARCH_LABEL, "All"), ]; } @@ -161,9 +170,9 @@ class SettingsForm extends ConfigFormBase { ->set(self::SEARCH_REMOVE_OPERATOR, $form_state->getValue(self::SEARCH_REMOVE_OPERATOR)) ->set(self::FACET_TRUNCATE, $form_state->getValue(self::FACET_TRUNCATE)) ->set(self::SOLR_CASE_INSENSITIVE_FIELD_PREFIX, $form_state->getValue(self::SOLR_CASE_INSENSITIVE_FIELD_PREFIX)) - ->set(self::LUCENE_SEARCH_FLAG, $form_state->getValue(self::LUCENE_SEARCH_FLAG)) - ->set(self::LUCENE_SEARCH_LABEL, $form_state->getValue(self::LUCENE_SEARCH_LABEL)) - + ->set(self::EDISMAX_SEARCH_FLAG, $form_state->getValue(self::EDISMAX_SEARCH_FLAG)) + ->set(self::EDISMAX_SEARCH_LABEL, $form_state->getValue(self::EDISMAX_SEARCH_LABEL)) + ->set(self::SEARCH_ALL_FIELDS_FLAG, $form_state->getValue(self::SEARCH_ALL_FIELDS_FLAG)) ->save(); parent::submitForm($form, $form_state); } @@ -175,6 +184,6 @@ class SettingsForm extends ConfigFormBase { * returns it as a form (renderable array). */ public function LuceneSearchEnableDisableCallback($form, FormStateInterface $form_state) { - return $form['lucene']['textfields_container']; + return $form['edismax']['textfields_container']; } }