First things first, Apache Solr is brilliant. It’s a branch of the Apache Lucene search project, and gives you blindingly-fast, scored search results. Or, as they say themselves…
Solr is the popular, blazing fast open source enterprise search platform from the Apache Lucene project. Its major features include powerful full-text search, hit highlighting, faceted search, dynamic clustering, database integration, and rich document (e.g., Word, PDF) handling. Solr is highly scalable, providing distributed search and index replication, and it powers the search and navigation features of many of the world’s largest internet sites.
There are some drawbacks to this though. First, as it’s a Java server, you have to run it on Jetty or Tomcat. Secondly, the Lucene syntax is a bit tricky to get your head around and get right. Thirdly, with the exception of the Apache’s PHP-Solr-Client, there’s not much information out there on putting into PHP. Until now…
The starting point of this CodeIgniter library was to create something that abstracted the Solr logic and was able to be programmed similar the CodeIgniter Active Record class. In all the examples below, I’ve written the logic as if it was written in the controller. However, under MVC standards, this really should all be a function in a model.
Download
Install to your CodeIgniter root folder. In the config/solr.php file, you’ll need to put in your connection details. In the ‘solr_config’ array, you’ll see “show_errors”. For development, set to true but it’s always a good idea to set to false when the site goes live. If there are any Solr errors, it displays them instead of outputting.
The “table” is also important. Solr does not have tables like MySQL does. What you have to do, when uploading the schema, is to add the “table” name to the schema and give it a name. Then we are able to select the “table” in Solr.
Simple Select Query
The basic syntax is identical to the CodeIgniter Active Record class.
$this->solr->select()
->from('table_name')
->where('col_name', 'value')
->order_by('order', 'ASC')
->limit(10);
$arrSolr = $this->solr->qAssoc();
This produces the MySQL equivalent of SELECT * FROM `table_name` WHERE `col_name` = ‘value’ LIMIT 10;
Let’s go through this chained query in detail.
$this->solr->select()
Opens up the select statement. You can specify “column” names. $this->solr->select(‘col_name’);
->from('table_name')
Does exactly what it says on the tin.
->where('col_name', 'value')
A simple where statement. By default, Solr uses the “OR” operator.
->where('col_name', 'value')
->where('other_col_name', 'other_value')
This would be the same as MySQL “WHERE `col_name` = ‘value’ OR `other_col_name` = ‘other_value’; You can add ’=’ or ‘!=’ after the column name to give AND declarations.
->where('col_name =', 'value')
->where('other_col_name !=', 'other_value)
This now means “WHERE `col_name` = ‘value’ AND `other_col_name` != ‘other_value’;
->order_by('order', 'ASC');
Same as the MySQL equivalent. One of the best things about Solr is that, by default, it will generate the relevancy of the terms submitted to what’s in it’s schema. If you don’t specify an order_by(), it will return it in relevancy order. As Solr is mostly designed to be used as a search engine, this is usually the order you want to return it in anyway.
->limit(10);
Exactly the same as the MySQL one. That means it only returns the first 10 rows. NB. Because of the way Solr works, it will ALWAYS limit it’s results. Fortunately, you’ve also got the offset command….
->limit(10, 20);
Then we execute
$arrSolr = $this->solr->qAssoc();
This executes the Solr statement and returns a mutli-level associative array. If there is nothing to return, it will return false. You will get returned everything you selected in the select() command and a node with the ‘score’.
Array
(
[0] => Array
(
[col1] => val1
[col2] => val2
[col3] => val3
[score] => 1
)
[1] => Array
(
[col1] => val4
[col2] => val5
[col3] => val6
[score] => 0.9
)
)
Now you will have a basic Solr library installed. There are more advanced things you can do with the library such as pagination, facetting and date ranges, which I shall cover in a future post.




[...] How to use solr on codeigniter? Mike Gioia This article has a good starting point: http://www.simonemms.com/code/co…Although it implements a pretty basic set up similar to active record. Any faceted or location based [...]
If we use this library, then, we replace our normal db calls with solr calls? I’ve been using sunspot/solr on rails apps, and now have to do some coding in CI (which I’m less used to). Sunspot has syntax for defining documents in the model. Doesn’t seem like your library does. Can you clarify how to use it in one’s app? Thanks.
No idea. It’s not designed with that in mind
Thanks for this, Simon.
How does one add new documents to the index?
At the moment, my Solr library only retrieves data. If you need to use this soon, I’d suggest using my class as a basis and write an insert() and update() method.
Information on how to do it is here – http://lucene.apache.org/solr/tutorial.html#Indexing+Data
In case you’re interested, I’m currently working on a complete rewrite of the Solr library and to make it framework independent. Details can be found at http://code.google.com/p/solrsystem/
S
I need to import the data from solr
Fatal error: Uncaught exception ‘Exception’ with message ‘”400″ Status: Bad Request’ in C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\application\libraries\SolrPHPClient\Service.php:335 Stack trace: #0 C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\application\libraries\SolrPHPClient\Service.php(965): Apache_Solr_Service->_sendRawGet(‘http://192.168….’) #1 C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\application\libraries\Solr.php(616): Apache_Solr_Service->search(‘ +type:*:*’, ’0′, 10, Array, ‘GET’) #2 C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\application\libraries\Solr.php(144): MY_Solr->search() #3 ———–\controllers\permission.php(165): MY_Solr->qAssoc() #4 [internal function]: Permission->showsolr() #5 C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\system\core\CodeIgniter.php(339): call_user_func_array(Array, Array) #6 C:\Program Files\NuSphere\TechPlat\apache\htdocs\skyfu2\index.php(204): in —————-\SolrPHPClient\Service.php on line 335
I’ve not written this with import in mind. Afraid you’ll have to look at that yourself.
One observation though – why are you running PHP on a Windows machine? Bet you that’s something to do with your error
how to get all data from the solr
I have imported data into solr and has been indexed how to get all the data
get all the data
function getSearch($query = null, $offset = false, $limit = false, array $params = null, $method = false){
/* Check we’ve got a connection */
/* TRY 5 times to connect */
for($i=1;$iconnected) { $this->connect(); }
}
/* Confirm we’ve made a connection before running query */
if($this->connected) {
/* Run the query */
$objResponse = parent::search($query, $offset, $limit);
/* Convert the response so we can use it usefully */
$this->_objHeader = $objResponse->responseHeader; // Header object
$this->_objResponse = $objResponse->response; // Docs returned
$this->num_rows = $this->_objResponse->numFound; // Total number of rows
$this->start = $this->_objResponse->start; // This should be the same as $offset
$this->limit = $limit; // The limit
//print_r($objResponse);
if($this->num_rows > 0) {
$arrQuery = array();
foreach($this->_objResponse->docs as $doc) {
/* Oddly, the docs object returns keys and values separately */
$arrKeys = $doc->getFieldNames();
/* Remove any prepends for name crashes */
if(!is_null($this->_from)) {
$regex = $this->_from.’\_’;
/* Avoid the primary key being replaced */
$arrKeys = preg_replace(“/^({$regex}id)/”, $this->_from.’_\\1′, $arrKeys);
$arrKeys = preg_replace(“/^({$regex})/”, ”, $arrKeys);
}
/* Replace key names */
if(is_array($this->_arrAs) && count($this->_arrAs) > 0) {
foreach($this->_arrAs as $old => $new) {
$oldId = array_search($old, $arrKeys);
$arrKeys[$oldId] = $new;
}
}
$arrQuery[] = array_combine($arrKeys, $doc->getFieldValues());
}
$this->_clean();
return $arrQuery;
} else {
/* Nothing found */
$this->_clean();
return false;
}
/* Return the object created the parent */
//return $objResponse;
}
//$solr->search($query, $offset, $limit)
}
$offset = 0;
$limit = 10;
$query = ‘*:*’;
$arrSolr = $this->solr->getSearch($query,$offset,$limit);