El tutorial Jobeet

17.3. Búsquedas

Ahora que ya tenemos todo preparado, vuelve a cargar los archivos de datos para que se cree el índice:

$ php symfony propel:data-load --env=dev

En esta ocasión, la tarea propel:data-load la ejecutamos con la opción --env porque el índice depende del entorno de ejecución y el entorno por defecto de las tareas es cli.

Nota Si eres usuario de sistemas operativos tipo Unix, ten en cuenta que el índice se modifica tanto desde la línea de comandos como desde la web, por lo que debes establecer los permisos adecuados al directorio donde guardas el índice. Comprueba tu configuración para que tanto el usuario de la línea de comandos como el usuario con el que se ejecuta el servidor web tengan permisos de escritura en el directorio de los índices.

Nota Si no has compilado la extensión zip para tu PHP, puede que se muestren algunos mensajes de aviso sobre la clase ZipArchive. Se trata de un error conocido de la clase Zend_Loader.

Después de crear los índices, añadir el buscador en la aplicación frontend es realmente sencillo. Como siempre, primero crea la ruta asociada:

job_search:
  url:   /search
  param: { module: job, action: search }

A continuación, crea la acción correspondiente:

// apps/frontend/modules/job/actions/actions.class.php
class jobActions extends sfActions
{
  public function executeSearch(sfWebRequest $request)
  {
    if (!$query = $request->getParameter('query'))
    {
      return $this->forward('job', 'index');
    }

    $this->jobs = JobeetJobPeer::getForLuceneQuery($query);
  }

  // ...
}

La plantilla asociada a esta acción también es muy sencilla:

// apps/frontend/modules/job/templates/searchSuccess.php
<?php use_stylesheet('jobs.css') ?>

<div id="jobs">
  <?php include_partial('job/list', array('jobs' => $jobs)) ?>
</div>

En realidad, la búsqueda se delega al método getForLuceneQuery():

// lib/model/JobeetJobPeer.php
static public function getForLuceneQuery($query)
{
  $hits = self::getLuceneIndex()->find($query);

  $pks = array();
  foreach ($hits as $hit)
  {
    $pks[] = $hit->pk;
  }

  $criteria = new Criteria();
  $criteria->add(self::ID, $pks, Criteria::IN);
  $criteria->setLimit(20);

  return self::doSelect(self::addActiveJobsCriteria($criteria));
}

Después de obtener todos los resultados del índice de Lucene, filtramos las ofertas de trabajo que no están activas y limitamos el número de resultados a un máximo de 20.

Para que el buscador esté completo, actualiza el layout:

// apps/frontend/templates/layout.php
<h2>Ask for a job</h2>
<form action="<?php echo url_for('@job_search') ?>" method="get">
  <input type="text" name="query" value="<?php echo $sf_request->getParameter('query') ?>" id="search_keywords" />
  <input type="submit" value="search" />
  <div class="help">
    Enter some keywords (city, country, position, ...)
  </div>
</form>

Nota Zend Lucene define su propio lenguaje para realizar consultas avanzadas que permite incluir operadores booleanos, comodines, búsquedas difusas y muchas otras cosas. Todas estas opciones están perfectamente documentadas en el manual del Zend Framework.