====== Multiple word search ======
Extend basic function to multiple word search (AND/OR condition).
\\
Applicable only to **one** search block.
\\
\\
**IMPORTANT NOTE**
\\
\\
There is a bug in the solr-tomcat package which emits a required library (lucene-memory.jar) from Solr include path.\\
The bug only becomes apparent when you search for an exact match.\\
All that needs to be done is this:
cd /usr/share/solr/WEB-INF/lib
ln -s ../../../java/lucene-memory.jar lucene-memory.jar
sudo service tomcat6 restart
\\
\\
* Edit **''/sites/all/modules/islandora_solr_search/IslandoraSolrQueryProcessor.inc''**:
solrLimit = variable_get('islandora_solr_search_num_of_results', 20);
global $base_url, $facetArray; //used by facet block as well
// -- cut here --
// Get display profile
$islandora_solr_primary_display = variable_get('islandora_solr_primary_display', 'default');
$profiles = module_invoke_all("islandora_solr_primary_display");
if (!isset($profiles[$islandora_solr_primary_display])) {
drupal_set_message("There is an error in the solr search configuration: the display profile is not found.", 'error');
return "";
}
$profile = $profiles[$islandora_solr_primary_display];
// Include the file for the display profile
require_once (drupal_get_path('module', $profile['module']) . '/' . $profile['file']);
// Set display class and function vars
$solrClass = $profile['class'];
$solrFunction = $profile['function'];
// -- end cut here --
//fix the query as some characters will break the search : and / slash are examples
$this->solrQuery = restoreSlashes($query);
if (empty($this->solrQuery)) {
// $this->solrQuery = '%20'; //so we can allow empty queries to dismax
}
$facetArray = array();
$facetFields = '';
$rawFacetVals = variable_get("islandora_solr_search_block_facets", 'dc.subject,dc.type');
$facetArray = islandora_build_substitution_list($rawFacetVals);
$facetFields = implode(",", array_keys($facetArray));
$facetlimit = variable_get('islandora_solr_search_block_facet_limit', '12');
$facetMinCount = variable_get('islandora_solr_search_block_facet_min_count', '2');
$requestHandler = variable_get("islandora_solr_search_block_request_handler", "standard");
$this->solrParams = array('facet' => 'true', 'facet.mincount' => $facetMinCount, 'facet.limit' => $facetlimit, 'qt' => $requestHandler, 'facet.field' => explode(',', $facetFields), //comma separated list configured in the block config
);
$debugQuery = (variable_get('islandora_solr_search_debug_mode', 0) ? "true" : null); //any val incl. 'false' is treated as true by Solr
// $fq = preg_replace('/PID:.*\*/', '', $fq);
if ($fq != NULL && $fq != '-') {
$fq = restoreSlashes($fq); //put the slash back
$fqs = csv_explode(IslandoraSolrQueryProcessor::$facetSeparator, $fq, '"', true); //to filter by more then one facet we will separate them by~ for nowseparate them by~ for now
$this->solrParams['fq'] = $fqs;
$islandora_fq = replaceSlashes($fq); //remove the slash here as we will be using this in url's
}
if (empty($islandora_fq)) {
$islandora_fq = '-';
}
if ($dismax != NULL) {
$this->solrDefType = $dismax;
$this->solrParams['defType'] = $dismax;
}
$this->solrStart = max(0, $startPage) * $this->solrLimit;
Tip
// The breadcrumb should go in the display class
$queryurl = "islandora/solr/search/" . replaceSlashes($this->solrQuery);
$breadcrumb_fq = $islandora_fq;
if (strcmp($islandora_fq, "-")) {
foreach(csv_explode(IslandoraSolrQueryProcessor::$facetSeparator, $islandora_fq, '"', true) as $facet) {
$field = substr($facet, 0, strpos($facet, ":"));
if ($field !== "rels.hasModel") {
$value = restoreSlashes(trim(substr($facet, strpos($facet, ":") + 1), '"'));
$options = array('html' => true);
$options['attributes']['title'] = $facet;
$crumblink = $queryurl . "/" . $breadcrumb_fq . (empty($this->solrDefType) ? '' : '/' . $this->solrDefType);
$cut_fq = $this->delete_filter($islandora_fq, $facet);
$cutlink = $queryurl . "/" . $cut_fq . (empty($this->solrDefType) ? '' : '/' . $this->solrDefType);
if (!strncmp("-", $facet, 1)) {
$options['attributes']['class'] = "strikethrough";
}
$breadcrumb[] = l($value, $crumblink, $options) . " (" . l("x", $cutlink, array('attributes' => array('title' => "Remove " . $facet))) . ")";
$breadcrumb_fq = $this->delete_filter($breadcrumb_fq, $facet);
}
}
}
if (!empty($this->solrQuery) && strcmp($this->solrQuery, ' ')) {
$cutlink = "islandora/solr/search/ /" . $islandora_fq . "/dismax";
$queryval = $this->solrQuery;
$tokens = explode(" ", $queryval);
foreach($tokens as $token) {
preg_match("/^.*:/", $token, $matches);
$queryval = str_replace($matches[0], "", $queryval);
}
if ($queryval != '%252F') {
$elencoparole = preg_replace('~\s+~', ' ', trim($queryval));
$searchwords = explode(" ", $elencoparole);
$elencoparole = "" . $searchwords[0] . "";
$nparole = count($searchwords);
if ($nparole > 2) {
for ($i = 1; $i < ($nparole - 1); $i++) {
$elencoparole.= " " . $searchwords[$nparole - 1] . " " . "" . $searchwords[$i] . "";
}
}
$elencoparole.= " °";
$breadcrumb[] = $elencoparole;
// $breadcrumb[] = l($queryval, $queryurl . "/-", array('attributes' => array('title' => $this->solrQuery))) .
// " (" . l("x", $cutlink, array('attributes' => array('title' => "Remove " . $facet))) . ")";
}
}
// $breadcrumb[] = l(t('Home'), NULL);
$breadcrumb[] = "Search";
if (!empty($breadcrumb)) $breadcrumb = array_reverse($breadcrumb);
drupal_set_breadcrumb($breadcrumb);
$this->solrFilters = $islandora_fq;
// if (strpos($fq, "rels.hasModel%253AbookCModel") === FALSE) {
// if ($fq) {
// $fq .= $this->facetSeparator;
// }
// $fq = "rels.hasModel%253AbookCModel";
// }
// At this point let's invoke a hook for third-party modules to mess about
// with the query parameters if they need to. Third party modules may alter
// this object's query parameters if they wish.
// module_invoke_all("islandora_solr_search_query_processor", &$this);
return;
}
/**
* Execute the query
* @return type
*/
function executeQuery()
{
// //////////////////////////////////////////////////////////////////////////// //
// Right here the function should be split. One function to execute the query, //
// another to set up pager variables and generate display. //
// //////////////////////////////////////////////////////////////////////////// //
$url = variable_get('islandora_solr_search_block_url', 'http://localhost:8080/solr');
$pathParts = parse_url($url);
$solr = new Apache_Solr_Service($pathParts['host'], $pathParts['port'], $pathParts['path'] . '/');
$solr->setCreateDocuments(0);
$this->solrParams['hl'] = 'true';
$this->solrParams['hl.fl'] = '*';
$this->solrParams['hl.requireFieldMatch'] = 'true';
$this->solrParams['hl.snippets'] = '10';
$this->solrParams['hl.simple.pre'] = '';
$this->solrParams['hl.simple.post'] = '';
Tip
$bcksolrQuery = $this->solrQuery;
$bcksolrQuery = preg_replace('~\s+~', ' ', trim($bcksolrQuery));
$termini = explode(":", $bcksolrQuery);
$parole = explode(" ", trim($termini[1]));
$numeroparole = count($parole);
$bcksolrQuery = "";
$bcksolrQuery = "(" . $termini[0] . ":" . $parole[0] . ")";
if ($numeroparole > 1) {
for ($i = 1; $i < $numeroparole; $i++) {
$bcksolrQuery = $bcksolrQuery . $termini[2] . "(" . $termini[0] . ":" . $parole[$i] . ")";
}
}
// This is where the query gets executed and output starts being created.
try {
// $results = $solr->search($this->solrQuery, $this->solrStart, $this->solrLimit, $this->solrParams);
$results = $solr->search($bcksolrQuery, $this->solrStart, $this->solrLimit, $this->solrParams);
}
catch(Exception $e) {
drupal_set_message(t('error searching ') . $e->getMessage());
}
$this->solrResult = $results;
if (empty($results)) {
drupal_set_message(t('Error searching solr index. Is the solr search block configured properly?'), 'error');
return;
}
unset($results);
unset($solr);
return;
}
...
}
* Edit **''/sites/all/modules/islandora_solr_search/IslandoraSolrResults.inc''**:
Tip
/**
* Build solr search form
* @param type $repeat
* @param type $pathToSearchTerms
* @param type $query
* @return string
*/
function build_solr_search_form($repeat = NULL, $pathToSearchTerms = NULL, $query = NULL)
{
$types = array();
$terms = trim(variable_get('islandora_solr_searchterms', 'dc.title ~ Title,dc.subject ~ Subject'));
$termsArray = preg_split('/[\n]/', $terms);
foreach($termsArray as $term) {
$vals = split('~', $term);
if (!$vals[1]) {
$vals[1] = $vals[0];
}
$types[trim($vals[0]) ] = trim($vals[1]);
}
$queryArray = NULL;
if (isset($query)) {
$termini = explode(":", $query);
$andOrs[] = trim($termini[2]);
$queryArray = preg_split('/( OR | AND )/', $query, 0, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
// foreach ($queryArray as $key => $val) {
// if ($val === ' OR ' || $val === ' AND ') {
// $andOrs[] = trim($val); // that is, just 'OR' or 'AND'
// unset($queryArray[$key]); //remove that from the array
// }
// }
$queryArray = array_values($queryArray);
}
$andOrArray = array('AND' => 'and', 'OR' => 'or',);
$form = array();
if (!isset($repeat)) {
$repeat = variable_get('islandora_solr_search_block_repeat', '3');
}
$var0 = explode(':', $queryArray[0]);
$form['search_type']['type1'] = array('#title' => 'Field', '#type' => 'select', '#options' => $types, '#default_value' => trim($var0[0]));
$form['fedora_terms1'] = array('#size' => '24', '#type' => 'textfield', '#title' => 'One or more words', '#default_value' => (count($var0) >= 2 ? restoreSlashes(trim($var0[1], '()')) : ''),);
// if ($repeat > 1 && $repeat < 9) { //don't want less then 2 or more then 9
if ($repeat > 0 && $repeat < 9) { //don't want less then 2 or more then 9
// for ($i = 2; $i < $repeat + 1; $i++) {
for ($i = 1; $i < $repeat + 1; $i++) {
$t = $i - 1;
// $j = $i - 2;
$j = $i - 1;
$andorj = (isset($andOrs[$j]) ? $andOrs[$j] : 'AND');
$field_and_term = explode(':', $queryArray[$t]);
$form["andor$t"] = array('#title' => 'Words boolean', '#type' => 'select', '#default_value' => $andorj, '#options' => $andOrArray);
/*
$form['search_type']["type$i"] = array(
'#title' => '',
'#type' => 'select',
'#options' => $types,
'#default_value' => trim($field_and_term[0])
);
$form["fedora_terms$i"] = array(
'#size' => '24',
'#type' => 'textfield',
'#title' => '',
'#default_value' => (count($field_and_term) >= 2 ? trim($field_and_term[1], '()') : ''),
);
*/
}
}
$form['submit'] = array('#type' => 'submit', '#value' => t('Search'));
return $form;
}
...
/**
* Theme solr search form
* @param type $form
* @return type
*/
function theme_solr_search_form($form)
{
if (!isset($repeat)) {
$repeat = variable_get('islandora_solr_search_block_repeat', '3');
}
$output = drupal_render($form['search_type']['type1']);
$output.= drupal_render($form['fedora_terms1']);
// $output.= drupal_render($form['andor1']) . drupal_render($form['search_type']['type2']);
$output.= drupal_render($form['andor1']);
/*
$output .= drupal_render($form['fedora_terms2']);
if ($repeat > 2 && $repeat < 9) {
for ($i = 3; $i < $repeat + 1; $i++) {
$t = $i - 1;
$output .= drupal_render($form["andor$t"]) . drupal_render($form['search_type']["type$i"]);
$output .= drupal_render($form["fedora_terms$i"]);
}
}
$output .= drupal_render($form['submit']);
*/
$output.= drupal_render($form);
return $output;
}
}
* Edit **''/sites/all/modules/islandora_solr_search/islandora_solr_search.module''**:
Tip
// append AND or OR at the end of string
$searchString.= ":" . trim($form_state['values']["andor0"]);
//
$searchString = trim($searchString);
$searchString = htmlspecialchars(drupal_urlencode($searchString), ENT_QUOTES, 'utf-8', false);
$searchString = str_replace('/', '~slsh~', $searchString); //replace the slash so url doesn't break
drupal_goto("islandora/solr/search/$searchString/-");
}
...
Download {{:frontend:islandorasolr.tar.gz|}} (IslandoraSolrQueryProcessor.inc, IslandoraSolrResults.inc, islandora_solr_search.module)