3,824 total views, 2 views today

 

Imagine that you have millions of data and your SQL database is not optimized enough to handle them, then “Solr” is your best data source. Apache Solr is a fast search platform. It’s major features include full-text search faceted search, dynamic clustering, database integration, rich document handling. Solr is highly scalable and it is the most popular enterprise search engine.

This document will guide you through DataSource setup for Solr in CakePHP. Set-up the Solr DataSource in CakePHP and query Solr with your CakePHP model “find” function, just similar to querying any other SQL database.

/app/Config/database.php:

Configuring your the DataSource for Solr database connection:

  • host: Solr server address.
  • port: Solr server port.
  • datasource: This should match with your DataSource at /app/Model/Datasource/SolrSource.php
class DATABASE_CONFIG {
public $solr = array(
 'datasource' => 'SolrSource',
 'host' => '192.168.2.131',
 'port' => '9983',
 'path' => '/solr/'
 );
 }

/app/Model/Solr.php:

Use the database config in your models like:

class Solr extends AppModel {
 public $useTable = false;
 public $useDbConfig = 'solr';
 }

/app/Model/Datasource/SolrSource.php:

Below code describes only the most required functions.

  • You can find other required functions at http://book.cakephp.org/2.0/en/models/datasources.html
    Like: calculate($model, $func, $params) and others create(), update(), delete().
  • Below DataSource only implements read() function.
  • Create a file called SolrSource.php and use below code:
App::uses('HttpSocket', 'Network/Http');
 require_once($_SERVER['DOCUMENT_ROOT'].'/root_folder/app/Vendor/Apache/Solr/Service.php');
 class SolrSource extends DataSource {

protected $_schema = array();
 protected $_host;
 protected $_port;

public function __construct($config){
 parent::__construct($config);
 $this->Http = new HttpSocket();

$this->host = $config['host'];
 $this->port = $config['port'];
 $this->_schema = $config['path'];

$this->solr=new Apache_Solr_Service($this->host, $this->port, $this->_schema);
 }

public function read(Model $model, $queryData = array(), $recursive = null) {
 $results = array();
 $query = $queryData['conditions']['solr_query'];
 if (Configure::read('log_solr_queries') === true) {
 CakeLog::write('debug', $query); /* Logs the solr query in app/tmp/logs/debug.log file */
 }

try {
 $solr_docs = $this->solr->search($query, $queryData['offset'], $queryData['limit'], array('sort' => $queryData['order']));
 } catch (Exception $e) {
 CakeLog::write('error', $e->getMessage()); /* Logs the solr errors message in app/tmp/logs/error.log file */
 CakeLog::write('error', $query); /* Logs the solr query in app/tmp/logs/error.log file */
 }
 $model->params = $solr_docs->responseHeader->params;
 $model->numFound = $solr_docs->response->numFound;
 $docs = $solr_docs->response->docs;
 foreach ($docs as $doc) {
 $document = array();
 foreach ($doc as $fieldName => $fieldValue) {
 $document[$fieldName] = $fieldValue;
 }
 $results[] = $document;
 }
 return array($model->alias => $results);
 }
 }

/app/Controller/UsersController.php:

Getting data from Solr server by using above SolrSource.

App::uses('AppController', 'Controller');
 class UsersController extends AppController {

public $name = 'Users'; //Controller name
 public $uses = array('Solr'); //Model name

function beforeFilter(){
 parent::beforeFilter();
 $this->Auth->allow('index');
 }

public function index(){
 $cond = "active:1";
 $sort = "timestamp desc";

$params = array(
 'conditions' =>array(
 'solr_query' => $cond
 ),
 'order' => $sort,
 'offset' => 0,
 'limit' => 1
 );

$result = $this->Solr->find('all', $params);
 $this->layout = 'ajax';
 header('Content-Type: application/json; charset=utf-8'); /* To send response in json format */
 echo json_encode($result);
 die;
 }
 }

See Also : How to use ‘neighbors’ with ‘find’ method

Debugging:

The above code has been tested and validated with CakePHP 2.2.3, PHP 5.3.1 .
Incase you face any problems:

  • First check the DataSource configuration in /app/Config/database.php.
  • Check /app/Model/Solr.php for this line: public $useDbConfig = ‘solr’;
  • Make sure Solr Service Vendor loaded in /app/Model/Datasource/SolrSource.php.
  • Check the path is correct for the Solr vendor.

Hope you liked this. Let me know if you want to add anything?