Kompletter Node in Solr Document ablegen

Dez 10 2009

Es kommt immer wieder vor, dass die Standard-Ausgabe der Suchresultate nicht wie vom Kunden gewünscht daher kommt. Zwar kann man in den Feldeinstellungen des Inhaltstypen für die Suche bestimmen welche Felder für die Anzeige verwendet werden sollen, aber dies ist unzureichend wenn man spezifische Vorgaben für die Darstellung hat. Daher ist man darauf angewiesen, die komplette Node für die Anzeige auszulesen.

Nun ist es aus meiner Sicht nicht das optimalste, bei der Anzeige der Resultate die Node jeweils mit node_load() für die Ausgabe zu laden (Performance). Daher macht es Sinn, die wichtigen Informationen der Node gleich im Solr-Dokument mit abzuspeichern. Dies kann wie folgt eingerichtet werden:

Zusätzliche Felddefinition im Solr-Dokument

Es gibt zwar dynamische Felddefinitionen welche verwendet werden könnten um das schema.xml nicht anpassen zu müssen. Diese Felddefinitionen indexieren aber immer die Inhalte was nur zum Speichern der Nodeinformationen nicht notwendig ist. Daher habe ich eine zusätzliche Felddefinition (node_store) hinzugefügt:

<!-- SPECIFIC FIELD TO STORE NODE -->
<field name="node_store" type="text" indexed="false" stored="true"/>

Node beim Indexieren im Solr-Dokument speichern

Vor dem Speichern der Node sollten nicht benötigte Felder entfernt werden, damit die Solr-Dokumente nicht unnötig gross werden. Um Encoding-Probleme zu vermeiden wird der serialisierte String noch urlencode()'d.

/**
 * implementation of hook_apachesolr_update_index()
 */
function hook_apachesolr_update_index(&$document, $node) {
  // Add complete node to Solr-Document.
  // Set body and content to empty string to save index space
  unset($node->body);
  unset($node->content);

  $serialized = serialize($node);
  $document->addField('node_store', urlencode($serialized)); 
  // urlencode string to prevent encoding problems!
}

Query modifizieren damit das Feld zurückgegeben wird

Damit im Result-Set das neu hinzugefügte Feld zurückgegeben wird, muss die Query modifiziert werden:

/**
 * Implementation of hook_apachesolr_modify_query()
 */
function hook_apachesolr_modify_query(&$query, &$params, $caller) {
  // Get node_store filed in Solr response
  $params['fl'] = $params['fl'] .',node_store';
}

 Aufbereiten des Resultates zur Ausgabe

In der template.php des verwendeten Themes muss folgender Hook implementiert werden:

/**
 * Implementation of hook_preprocess_search_result()
 */
function hook_preprocess_search_result(&$vars) {
  // Set a variable with the complete node from the solr document
  $node_serialized = $vars['result']['node']->getField('node_store');
  $vars['node'] = unserialize(urldecode($node_serialized['value']));
}

Danach kann die Variable $node im Template 'search-result.tpl.php' zur Ausgabe verwendet werden. Ein einfaches Beispiel:

<span class="CLASS"><?php print $node->field_name[0]['value']?></span>

So einfach kann das Solr-Dokument mit zusätzlichen Informationen angereichert werden, welche bei der Verarbeitung zur Ausgabe notwendig sind.

mit der an diesem Datum

mit der an diesem Datum aktuellen Version funktioniert das so leider nicht.

Was funktioniert bei Dir

Was funktioniert bei Dir nicht?