如何使用Apache SOLR和PHP代码突出显示搜索结果

时间:2010-11-03 11:50:10

标签: php solr

任何人都可以指导我突出显示Solr搜索结果的方法。我使用DomDocument来解析xml结果。

在这里,我有如下的示例文档。

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

我通过使用以下功能

获取搜索结果
 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;
 }

...

在我的结果页面中,我显示了如下数据

$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;
    } 
 }

以下是我对如何突出显示搜索结果感到困惑的代码。你可以帮帮我吗?

1 个答案:

答案 0 :(得分:3)

您无需在PHP中手动突出显示来自Solr的文档。 Solr already provides highlighting functionality

执行像http://path/to/solr:8983/?q=keyword&hl=true&hl.fl=title,text这样的Solr查询将返回类似:

的内容
<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>

现在您只需将id中的文档resultlst name="highlighting"中的文档进行匹配(使用Xpath可能是最简单的方法):

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

DOM的问题在于它在请求$node->nodeValue时剥离了HTML / XML标记,因此您将突出显示标记(<em>)将被剥离。您必须使用递归函数来提取所有标记,或者更简单的解决方案是使用SimpleXML及其asXML方法:

$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);
}