prabu
prabu

Reputation: 6171

How to Highlighting Search Results Using Apache SOLR with PHP code

Any one guide me the way to highlighting Solr search results. I am using DomDocument for to parse the xml results.

Here, I have the sample document like below.

<add><doc>
<field name="id">1</field><field name="title">Leason1</field>
<field name="description">XYZ</field>
</doc></add>

I am getting the search results by using below function,

 function solrQuery($q){

 $query = "?q=".trim(urlencode($q)).
"&version=2.2&start=0&rows=10&indent=on&hl=true&hl.fl=title";

 if($q != '')
   return $results = request("", "select".$query);
   return 0;
 }

....

In my result page I ve display the data like below,

$results = solrQuery($query);
if($results != ''){
$results = explode('<?xml version="1.0" encoding="UTF-8"?>', $results);
$results = $results[1];
$dom = new DomDocument;
$dom->loadXML($results);
$docs = $dom->getElementsByTagName('doc');
foreach ($docs as $doc) {
 $strings = $doc->getElementsByTagName('str');
 foreach($strings as $str){
   $attr = $str->getAttribute('name');
   $data = $str->textContent;
   switch($attr){
   case 'id':
    $id = $data;
    break;
   case 'title':
    $title = $data;
    break;
   case 'description':
    $description = $data;
    break;
    } 
 }

Here is the code I get confusion how to Highlight search results. Can you help me for this?

Upvotes: 2

Views: 9000

Answers (1)

netcoder
netcoder

Reputation: 67735

You don't have to manually highlight your documents from Solr in PHP. Solr already provides highlighting functionality.

Executing a Solr query like http://path/to/solr:8983/?q=keyword&hl=true&hl.fl=title,text will return something like:

<result name="response" numFound="1" start="0">
   <doc>
      <str name="id">myDocumentId</str>
      <str name="title">The title contains keyword</str>
      <str name="description">Keywords, keyword is highlighted.</str>
   </doc>
</result>
<lst name="highlighting">
   <lst name="myDocumentId">
      <str name="title">The title contains <em>keyword</em></str>
      <str name="description"><em>Keyword</em>s, <em>keyword</em> is highlighted.</str>
   </lst>
</lst>

Now all you have to to is to match the document id in result to the one in lst name="highlighting" (using Xpath is probably the easiest way):

//lst[@name='highlighting']/lst[@name='myDocumentId']/*

The problem with DOM is that it strips the HTML/XML tags when requesting $node->nodeValue, so you're highlighting tags (<em>) will be stripped. You have to use a recursive function to extract it with all the tags, or a simpler solution is to use SimpleXML with its asXML method:

$sxml = new SimpleXMLElement(file_get_contents('doc.xml'));
$nodes = $sxml->xpath("//lst[@name='highlighting']/lst[@name='myDocumentId']/*");

foreach ($nodes as $node) {
   $field = $node->attributes()->name;
   $tag = $node->getName();
   $value = $node->asXML();
   $value = preg_replace("/(<$tag name=\"$field\">|<\/$tag>)/", '', $value);
}

Upvotes: 3

Related Questions