Nachdem Sphinx und SphinxSE installiert ist, geht es diesmal um die Integration in ein Zend Framework-Projekt. Dazu gehört die Erstellung einer Konfigurationsdatei und ein Kommandozeilen-Skript zum Starten und Stoppen des Sphinx-Suchdämons und zum Generieren des Suchindexes.
Den Code zum Artikel gibts auf github.
Das Zend Framework ist nicht enthalten und muss noch nachinstalliert werden. Entweder man lädt sich die aktuelle Version herunter und kopiert oder linkt den Zend-Ordner ins library
-Verzeichnis oder man installiert es per PEAR. Den (inoffiziellen) PEAR Channel gibts unter http://pear.zfcampus.org.
Die Konfigurationsdatei von Sphinx ist die Schaltzentrale und enthält alle Optionen für den Dämon, den Indexer, die Indizes und deren Datenquellen. Für unser Beispielprojekt nutzen wir eine einfache Variante mit Grundeinstellungen. Der Clou ist, dass die Konfigurationsdateien von jeder beliebigen Skriptsprachen verarbeitet werden kann. Einfach am Anfang der Datei den entsprechenden Shebang setzen.
Die Datei liegt in application/configs/sphinx.conf
:
#!/usr/bin/env php <?php // Define path to application directory defined('APPLICATION_PATH') || define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/..')); // Define application environment // // Use `export APPLICATION_ENV=development` or edit /etc/environment // to change the application environment defined('APPLICATION_ENV') || define('APPLICATION_ENV', (getenv('APPLICATION_ENV') ? getenv('APPLICATION_ENV') : 'production')); // Ensure library/ is on include_path set_include_path(implode(PATH_SEPARATOR, array( realpath(APPLICATION_PATH . '/../../library'), get_include_path(), ))); /** Zend_Application */ require_once 'Zend/Application.php'; // Create application, bootstrap, and run $application = new Zend_Application( APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini' ); $config = $application->getOptions(); ?> source posts { type = mysql sql_host = <?php echo $config['resources']['db']['params']['host'] . "\n"; ?> sql_user = <?php echo $config['resources']['db']['params']['username'] . "\n"; ?> sql_pass = <?php echo $config['resources']['db']['params']['password'] . "\n"; ?> sql_db = <?php echo $config['resources']['db']['params']['dbname'] . "\n"; ?> # sql_port = 3306 # optional, default is 3306 sql_query_pre = SET NAMES utf8 sql_query = \ SELECT posts.id, posts.category_id, posts.title, posts.content, UNIX_TIMESTAMP(posts.created) AS created, \ categories.name AS category_name, \ GROUP_CONCAT(tags.tag SEPARATOR ', ') AS tags \ FROM posts \ JOIN categories ON (categories.id = posts.category_id) \ LEFT JOIN posts_tags ON (posts_tags.post_id = posts.id) \ LEFT JOIN tags ON (tags.id = posts_tags.tag_id) \ GROUP BY posts.id sql_attr_uint = category_id sql_attr_timestamp = created sql_query_info = \ SELECT posts.id, posts.category_id, posts.title, posts.content, posts.created, \ categories.name AS category_name, \ GROUP_CONCAT(tags.tag SEPARATOR ', ') AS tags \ FROM posts \ JOIN categories ON (categories.id = posts.category_id) \ LEFT JOIN posts_tags ON (posts_tags.post_id = posts.id) \ LEFT JOIN tags ON (tags.id = posts_tags.tag_id) \ WHERE posts.id=$id } index posts { source = posts path = <?php echo $config['sphinx']['index']['path']; ?>/posts docinfo = extern html_strip = 1 charset_type = utf-8 # Character table for german (from http://www.sphinxsearch.com/forum/view.html?id=19) charset_table = 0..9, A..Z->a..z, _, a..z, U+C4->U+E4, U+D6->U+F6, U+DC->U+FC, U+DF, U+E4, U+F6, U+FC } indexer { mem_limit = 32M } searchd { listen = <?php echo $config['sphinx']['searchd']['listen'] . "\n"; ?> log = <?php echo $config['sphinx']['searchd']['log'] . "\n"; ?> query_log = <?php echo $config['sphinx']['searchd']['query_log'] . "\n"; ?> read_timeout = 5 max_children = 30 pid_file = <?php echo $config['sphinx']['searchd']['pid_file'] . "\n"; ?> max_matches = 1000 seamless_rotate = 1 preopen_indexes = 0 unlink_old = 1 } |
Was die einzelnen Optionen bedeuten, kann man in der Dokumentation gut nachlesen. Ich will hier nur auf paar Besonderheiten eingehen:
Zend_Application
um die application.ini
zu laden.source posts
nutzen wir die ausgelesenen Optionen um die Zugangsdaten für die Datenbank zu setzen. Diese können dann global in der application.ini
verwaltet werden.index posts
und searchd
verwenden wir ebenfalls Optionen aus der application.ini
. Das sind vor allem Pfadangaben für den Suchindex und Logdateien und an welcher IP und/oder Port der Suchdämon lauschen soll. Diese Angaben können wir somit pro APPLICATION_ENV
anpassen.Um den Suchindex zu erstellen und den Suchdämon zu starten und zu stoppen, enthält das Projekt das Kommandozeilen-Skript in scripts/sphinx
. Der Aufruf erfolgt so:
$ ./scripts/sphinx COMMAND ENVIRONMENT |
start | Startet den Suchdämon. |
---|---|
stop | Stoppt den Suchdämon. |
restart | Startet den Suchdämon neu. |
index-all | Erstellt alle in application/configs/sphinx.conf definierten Suchindizes. |
Gibt APPLICATION_ENV
an, entspricht also define('APPLICATION_ENV', 'production');
in z. B. der index.php
. Somit wird der entsprechende Abschnitt in application/configs/application.ini
genutzt. Wenn nicht angegeben, wird standardmäßig production
verwendet.
Startet den Suchdämon mit APPLICATION_ENV=production
:
$ ./scripts/sphinx start production |
Erstellt alle Suchindizes mit APPLICATION_ENV=development
:
$ ./scripts/sphinx index-all development |
Somit haben wir nun unser Zend Framework-Projekt präpariert um mit Sphinx zu arbeiten. Auf den Suchindex lässt sich nun ganz einfach, z. B. per Zend_Db_Select, zugreifen:
$query = 'Mein Suchbegriff'; $select = $db->select(); $select->from('posts') ->joinInner('sphinx', 'sphinx.id = posts.id') ->where('sphinx.query = ?', $query . ';mode=any;sort=extended:@weight desc, @id asc;limit=10;offset=0;index=posts'); $result = $select->query()->fetchAll(); |