Merge pull request #20 from digitalutsc/contrib-edismax

Enabled edismax for field search as well
This commit is contained in:
Kyle Huynh 2023-02-01 09:58:30 -05:00 committed by GitHub
commit ed8c484e12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 128 additions and 59 deletions

View file

@ -154,15 +154,24 @@ class AdvancedSearchQuery {
// create a flag for active/inactive dismax // create a flag for active/inactive dismax
$isDismax = false; $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. // To support negative queries we must first bring in all documents.
$q[] = $this->negativeQuery($terms) ? "*:*" : ""; $q[] = $this->negativeQuery($terms) ? "*:*" : "";
$term = array_shift($terms); $term = array_shift($terms);
$q[] = $term->toSolrQuery($field_mapping); $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") { if ($term->getField() === "all") {
$isDismax = true; $isSearchAllFields = true;
} }
// for multiple conditions // for multiple conditions
@ -170,41 +179,48 @@ class AdvancedSearchQuery {
$q[] = $term->getConjunction(); $q[] = $term->getConjunction();
$q[] = $term->toSolrQuery($field_mapping); $q[] = $term->toSolrQuery($field_mapping);
// new
$fields_list[] = $term->toSolrFields($field_mapping);
// set dismax is enabled if the field set to "all" // set dismax is enabled if the field set to "all"
if ($term->getField() === "all") { if ($term->getField() === "all") {
$isDismax = true; $isSearchAllFields = true;
}
}
}
}
$q = implode(' ', $q); $q = implode(' ', $q);
// Limit extra processing if Luncene Search is enable // Limit extra processing if Luncene Search is enable
if ($isDismax) { if ($isDismax) {
$case_insensitive_field = $this::getConfig(SettingsForm::SOLR_CASE_INSENSITIVE_FIELD_PREFIX, ''); $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 ((strpos($q, "*") !== false || strpos($q, "?") !== false)) {
// if the query string contain '*', '?', OR is a single world, enable wildcard // if the query string contain '*', '?', OR is a single world, enable wildcard
$tmp = str_replace('"', "", trim($q)); $tmp = str_replace('"', "", trim($q));
$query_fields = []; $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 ($isSearchAllFields) {
if ($case_insensitive_field !== '') { foreach ($field_mapping as $key => $field) {
$item_prefix = substr($item, 0, 3); foreach ($field as $f => $item) {
if ($item_prefix == "ss_" || $item_prefix == "sm_") { // bs_ are boolean fields, do not work well with text search
$case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); if (substr($item, 0, 3) !== "bs_" && !in_array($item, ['score', 'random', 'boost_document'])
array_push($query_fields, '('.$case_insensitive_item. ':'. $tmp .')'); && ((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 .')');
}
} }
}
}
} }
} }
} }
@ -217,22 +233,29 @@ class AdvancedSearchQuery {
$dismax = $solarium_query->getEDisMax(); $dismax = $solarium_query->getEDisMax();
$dismax->setQueryParser('edismax'); $dismax->setQueryParser('edismax');
$query_fields = []; $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 !== '') { if ($isSearchAllFields) {
$item_prefix = substr($item, 0, 3); foreach ($field_mapping as $key => $field) {
if ($item_prefix == "ss_" || $item_prefix == "sm_") { foreach ($field as $f => $item) {
$case_insensitive_item = str_replace($item_prefix,$case_insensitive_field, $item); // bs_ are boolean fields, do not work well with text search
array_push($query_fields, $case_insensitive_item); 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)); $query_fields = implode(" ", array_unique($query_fields));
$dismax->setQueryFields($query_fields); $dismax->setQueryFields($query_fields);
} }

View file

@ -3,7 +3,7 @@
namespace Drupal\advanced_search; namespace Drupal\advanced_search;
use Drupal\advanced_search\Form\AdvancedSearchForm; use Drupal\advanced_search\Form\AdvancedSearchForm;
use Drupal\advanced_search\Form\SettingsForm;
/** /**
* Defines a single search term. * Defines a single search term.
* *
@ -285,7 +285,10 @@ class AdvancedSearchQueryTerm {
$query_helper = \Drupal::service('solarium.query_helper'); $query_helper = \Drupal::service('solarium.query_helper');
$value = $query_helper->escapePhrase(trim($this->value)); $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 // Case 1: if keyword contains one word or a phrase
if(strpos(trim($value), ' ') !== false) { if(strpos(trim($value), ' ') !== false) {
@ -352,6 +355,30 @@ class AdvancedSearchQueryTerm {
$terms = implode(' ', $terms); $terms = implode(' ', $terms);
return $this->include ? "($terms)" : "-($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 * Get Field search
*/ */

View file

@ -103,14 +103,24 @@ class AdvancedSearchForm extends FormBase {
return self::getConfig(SettingsForm::SEARCH_REMOVE_OPERATOR, self::DEFAULT_REMOVE_OP); 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 * @return boolean
* *
*/ */
public static function getLuceneSearch() { public static function getSearchAllFields() {
return self::getConfig(SettingsForm::LUCENE_SEARCH_FLAG, 0); 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 * @return string
* The character to use for removing an facet to the query. * The character to use for removing an facet to the query.
*/ */
public static function getLuceneSearchLabel() { public static function getEdismaxSearchLabel() {
return self::getConfig(SettingsForm::LUCENE_SEARCH_LABEL, "All"); 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); $term_default_values = $this->defaultTermValues($options);
list($recursive, $term_values) = $this->processInput($form_state, $term_default_values); list($recursive, $term_values) = $this->processInput($form_state, $term_default_values);
$i = 0; $i = 0;

View file

@ -23,8 +23,9 @@ class SettingsForm extends ConfigFormBase {
const SEARCH_REMOVE_OPERATOR = 'search_remove_operator'; const SEARCH_REMOVE_OPERATOR = 'search_remove_operator';
const FACET_TRUNCATE = 'facet_truncate'; const FACET_TRUNCATE = 'facet_truncate';
const SOLR_CASE_INSENSITIVE_FIELD_PREFIX = "case_insensitive_solr_field_prefix"; const SOLR_CASE_INSENSITIVE_FIELD_PREFIX = "case_insensitive_solr_field_prefix";
const LUCENE_SEARCH_FLAG = 'lucene_on_off'; const EDISMAX_SEARCH_FLAG = 'lucene_on_off';
const LUCENE_SEARCH_LABEL = 'lucene_label'; const EDISMAX_SEARCH_LABEL = 'lucene_label';
const SEARCH_ALL_FIELDS_FLAG = 'all_fields_on_off';
/** /**
* Constructs a \Drupal\system\ConfigFormBase object. * Constructs a \Drupal\system\ConfigFormBase object.
@ -115,34 +116,42 @@ class SettingsForm extends ConfigFormBase {
], ],
]; ];
$form['lucene'] = [ $form['edismax'] = [
'#type' => 'fieldset', '#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', '#type' => 'checkbox',
'#title' => $this '#title' => $this
->t('Enable Lucene Search.'), ->t('Enable Extended DisMax Query.'),
'#default_value' => self::getConfig(self::LUCENE_SEARCH_FLAG, 0), '#default_value' => self::getConfig(self::EDISMAX_SEARCH_FLAG, 0),
'#ajax' => [ '#ajax' => [
'callback' => '::LuceneSearchEnableDisableCallback', 'callback' => '::LuceneSearchEnableDisableCallback',
'wrapper' => 'lucene-container', 'wrapper' => 'edismax-container',
'effect' => 'fade', 'effect' => 'fade',
], ],
]; ];
$form['lucene']['textfields_container'] = [ $form['edismax']['textfields_container'] = [
'#type' => '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', '#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.'), '#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::SEARCH_REMOVE_OPERATOR, $form_state->getValue(self::SEARCH_REMOVE_OPERATOR))
->set(self::FACET_TRUNCATE, $form_state->getValue(self::FACET_TRUNCATE)) ->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::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::EDISMAX_SEARCH_FLAG, $form_state->getValue(self::EDISMAX_SEARCH_FLAG))
->set(self::LUCENE_SEARCH_LABEL, $form_state->getValue(self::LUCENE_SEARCH_LABEL)) ->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(); ->save();
parent::submitForm($form, $form_state); parent::submitForm($form, $form_state);
} }
@ -175,6 +184,6 @@ class SettingsForm extends ConfigFormBase {
* returns it as a form (renderable array). * returns it as a form (renderable array).
*/ */
public function LuceneSearchEnableDisableCallback($form, FormStateInterface $form_state) { public function LuceneSearchEnableDisableCallback($form, FormStateInterface $form_state) {
return $form['lucene']['textfields_container']; return $form['edismax']['textfields_container'];
} }
} }