Reputation: 6171
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
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