Index für Volltextsuche
Trick zur Beschleunigung der Suche
Da eine Volltextsuche mit Related Tables zu absurd hohen Zeiten beim Ausführen der Queries führt (mit vielen Joins) habe ich hier einen Ausweg gefunden, der funktioniert solange
- die Daten nur im Backend editiert werden
- die Tabellen über mm Relation verbunden sind
Beim Speichern im Backend wird in ein eigenes Feld namens "full_text" eine kommaseparierte Liste der Einträge in Related Tables geschrieben.
Hook für Speichern im Backend
ext_localconf.php
include "class.tx_rsyssocialprojects_compat.php";
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tcemain.php']['processDatamapClass'][] = 'tx_rsyssocialprojects_compat';
Klasse
class.tx_rsyssocialprojects_compat.php:
<?php
class tx_rsyssocialprojects_compat {
/**
* executed on save in backend
*
* @param string status: new/update is relevant for us
* @param string db table
* @param integer record uid
* @param array record
* @param object parent object
* @return void
*/
function processDatamap_postProcessFieldArray($status, $table, $id, &$fieldArray, $pObj) {
if($table == 'tx_rsyssocialprojects_domain_model_project' && ($status == 'new' || $status == 'update')) {
if($status == 'update') {
$data = $this->getFullRecord($id);
} else {
$data = $fieldArray;
}
$newRecord = array_merge($data, $fieldArray);
$combinedName = '';
$combinedName .= $this->getRelated('admission', $id);
$combinedName .= $this->getRelated('goal', $id);
$combinedName .= $this->getRelated('place', $id);
$combinedName .= $this->getRelated('projecttype', $id);
$combinedName .= $this->getRelated('schooltype', $id);
$combinedName .= $this->getRelated('targetgroup', $id);
# write to fulltext field
$fieldArray['full_text'] = $combinedName;
}
}
/**
* gets a full tx_rsyssocialprojects_domain_model_project record
*
* @param integer $uid: lookup uid
* @return array data record with associative keys
*/
function getFullRecord($uid) {
$row = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
'*',
'tx_rsyssocialprojects_domain_model_project',
'uid = '.$uid
);
return $row[0];
}
/**
* gets a record from a related table
*
* @param string $name: table name
* @param string $uid: lookup uid
* @return array data record with associative keys
*/
function getRelated($name, $uid) {
$ret = '';
$res = $GLOBALS['TYPO3_DB']->sql_query(
'SELECT a.title FROM tx_rsyssocialprojects_domain_model_project p
LEFT JOIN tx_rsyssocialprojects_project_'.$name.'_mm mm ON mm.uid_local = p.uid
LEFT JOIN tx_rsyssocialprojects_domain_model_'.$name.' a ON mm.uid_foreign = a.uid
WHERE p.uid='.$uid
);
while ($row = $GLOBALS['TYPO3_DB']->sql_fetch_assoc($res)) {
$ret .= ','.$row['title'];
}
return $ret;
}
}
if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tt_data/class.tx_ttdata_compat.php']) {
include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/tt_data/class.tx_ttdata_compat.php']);
}
?>
Nun kann man bei der Volltextsuche ganz entspannt in dem Feld full_text suchen bei optimaler Performance. Vielen Dank an Sigi für die Idee hierzu :-)
So sieht das dann aus:
// related tables are stored in full text on save in backend
$query->like('fullText', "%".$searchText."%"),
// related tables - way too slow
//$query->like('projectTypes.title', "%".$searchText."%"),
//$query->like('targetGroups.title', "%".$searchText."%"),
//$query->like('goals.title', "%".$searchText."%"),
//$query->like('places.title', "%".$searchText."%"),
//$query->like('admissions.title', "%".$searchText."%"),
//$query->like('schoolTypes.title', "%".$searchText."%"),