Apache Solr search autocomplete

2019-04-07 19:37发布

问题:

I'm using apache solr search engine to implement my site search. I able to setup the Apache Solr Search module and now my search is working as I need. Now I trying to implement an search autocomplete with the help of Apache Solr Autocomplete module, but the thing is I'm trying to show the node titles as suggestion list rather than keywords. Finally I found this tutorial and tried that, I seems to be working but now I'm stucked with an AJAX HTTP error (500). And I found 4 error messages in my drupal error log:-

Notice: Undefined index: facet.prefix in apachesolr_autocomplete_suggest() (line 461 of /home/test/webroot/sites/all/modules/apachesolr_autocomplete/apachesolr_autocomplete.module).

Warning: Invalid argument supplied for foreach() in apachesolr_autocomplete_suggest() (line 470 of /home/test/webroot/sites/all/modules/apachesolr_autocomplete/apachesolr_autocomplete.module).

Notice: Trying to get property of non-object in apachesolr_autocomplete_suggest() (line 470 of /home/test/webroot/sites/all/modules/apachesolr_autocomplete/apachesolr_autocomplete.module).

Notice: Undefined property: stdClass::$payslip in apachesolr_autocomplete_suggest() (line 469 of /home/test/webroot/sites/all/modules/apachesolr_autocomplete/apachesolr_autocomplete.module).

I guess this tutorial almost doing the job we looking for, unfortunately they no longer providing support or any response to the comments. Is anyone able to figure out a way to implement this cool functionality? Even if anyone come up with a licence version, I'm happy to buy. Thanks guys.

This is the current Apache Solr Autocomplete look like (below image), In this suggestion list they listing the search keywords from the search index. What I'm trying to do is listing the node titles in this suggestion list.

回答1:

This is just a trick, not the not the correct way, but you can try.

First you should capture the Solr query, which executed when you hit search.

I use the solr level module to catch the query. Then create your own module with hooks.

/**
 * Implements hook_menu().
*/

function mymodule_menu() {
  $items = array();

  //create a call back for autocomplete search box
  $items['searchauto/autocomplete'] = array(
    'page callback' => 'mymodule_search_autocomplete',
    //'access arguments' => array('access search autocomplete'),
    'type' => MENU_CALLBACK,
    'access arguments' => array('access content'),
  );

  return $items;
}
/**

* hook_form_FORM_ID_alter
* solr search form text box autocomplete
**/
function mymodule_form_search_block_form_alter(&$form, &$form_state, $form_id) {

  $form['search_block_form'] = array(
  '#type' => 'textfield',
  '#autocomplete_path' => 'searchauto/autocomplete',
);
}
/**
a* call back function for autocomplete
**/
function mymodule_search_autocomplete($string) {

  unset($results);
  $results = array();
  $matches = array();

  //replace the space with %20
  $key = preg_replace('/[[:space:]]+/', '%20', $string);
  //number of results you want to show
  $num_result = 15;
  //your Solr server path
  $solr_server = "http://locathost/solr";

//this is the trick. first you should capture the Solr query, which executed when you hit search. I use the Solr level module to catch the query. you can change parameters if you want, I'm only changing the search keyword and number of results
$request_url = $solr_server."/select?start=0&rows=$num_result&&spellcheck=true&q=$key&fl=id%2Centity_id%2Centity_type%2Cbundle%2Cbundle_name%2Clabel%2Css_language%2Cis_comment_count%2Cds_created%2Cds_changed%2Cscore%2Cpath%2Curl%2Cis_uid%2Ctos_name%2Czm_parent_entity%2Css_filemime%2Css_file_entity_title%2Css_file_entity_url&mm=1&pf=content%5E2.0&ps=15&hl=true&hl.fl=content&hl.snippets=3&hl.mergeContigious=true&f.content.hl.alternateField=teaser&f.content.hl.maxAlternateFieldLength=256&spellcheck.q=$key&qf=content%5E40&qf=label%5E21.0&qf=tags_h1%5E3.0&qf=tags_h2_h3%5E3.0&qf=tags_inline%5E1.0&qf=taxonomy_names%5E2.0&qf=tos_name%5E3.0&facet=true&facet.sort=count&facet.mincount=1&facet.field=im_field_taxonomy_app_cat&f.im_field_taxonomy_app_cat.facet.limit=50&f.im_field_taxonomy_app_cat.facet.mincount=1&boost=eff_popularity&debugQuery=on&wt=json&json.nl=map";
//exit;
// Retrieve data from the external API
$response = drupal_http_request($request_url);

// Check the HTTP response code to see if a valid response was received
if($response->code >= 200 && $response->code < 300)
{

    //make sure response has values
    if(isset($response)){
      $results = (array) json_decode($response->data);
    }
    if(isset($results)){
      //dsm($results);
      //store the values into an array
      if(isset($results['response']->docs)){
        $arrResults = $results['response']->docs;
      }
    }

    //check array count
    if(count($arrResults) > 0){
        //loop the results and add to array for json return data
        foreach($arrResults as $row){
          //dsm($row);
          //print $row->label;
          //print "<br>";
          $matches[$row->url] = $row->label;
        }

    }
    else{
        $matches[''] = "No Results Found!";
    }
}
else{
    $matches[''] = "Check server settings!";
}

drupal_json_output($matches);

}