uvmcSolrSearchPlugin
uvmcSolrSearchPlugin for symfony 1.2
The umvcSolrSearchPlugin is a symfony plugin which permits you to index your models inside a solr service.
This readme assumes that you have already configured your solr service. If you want to learn how to setup a solr service,
you can read the official solr tutorial.
As of now, please consider this plugin as an ALPHA release.
The plugin hasn't been fully tested.
Installation
Check out from svn
svn co http://svn.symfony-project.org/plugins/uvmcSolrSearchPlugin/trunk uvmcSolrSearchPlugin
Clear your cache
php symfony cc
Configuration
Configure solr.yml
all:
enabled: on
servers:
master:
host: localhost
port: 8983
path: "/solr"
Configure your solr installation to enable php serialiazed array writers
In your/install/of/solr/conf/solrconfig.xml, uncomment those lines
<queryResponseWriter name="php" class="org.apache.solr.request.PHPResponseWriter"/>
<queryResponseWriter name="phps" class="org.apache.solr.request.PHPSerializedResponseWriter"/>
Add to the models you want to index the method getSolrDocumentFields()
public function getSolrDocumentFields()
{
// keys of this array are fields' name of solr's schema.xml
$fields = array('id' => $this->getId(),
'foo' => array('value' => $this->getFoo(),
'boost' => 1.4);
foreach($this->getBar() as $bar)
{
$fields['bar'][] = array('value' => $bar->getFoobar(),
'boost' => 1.1);
}
return $fields;
}
How to index/delete my model into solr?
In the admin generator
All the models which have the method getSolrDocumentFields() will be automagically indexed/deleted upon save/deletion.
In my code
Each time that you modify an indexable model, you have to notify the event dispatcher with the appropriate event. Otherwise, it won't work.
// ... my super code ...
$myModel->save();
$dispatcher = sfContext::getInstance()->getEventDispatcher();
$dispatcher->notify(new sfEvent($mySubject, 'uvmc_solr.add_document', array('object' => $myModel, 'commit' => true)));
// ... my ninja code ...
$dispatcher = sfContext::getInstance()->getEventDispatcher();
$dispatcher->notify(new sfEvent($mySubject, 'uvmc_solr.delete_document', array('object' => $myModel)));
$myModel->delete();
How to search?
Let's say you configured solr to only give you back the primary keys of your models.
Add this in myModelTable.class.php
public function findByScoredId($ids)
{
$query = $this->createQuery('p');
$query->select('p.*')
->whereIn('p.id', $ids)
// Keep scoring
// http://groups.google.com/group/symfony-users/browse_thread/thread/92adb0332dfe1065/ee7b8c0d27208368?lnk=gst&q=zend+search+sort#ee7b8c0d27208368
->addSelect('FIELD(p.id,'.implode(', ', $ids).') AS field')
->orderBy('field');
return $query->execute();
}
...and this in your action!
// Notify the dispatcher with the search event.
// $myQuery is a string containing your query
$event = $this->dispatcher->notify(new sfEvent($this, 'uvmc_solr.search', array('query' => $myQuery)));
$response = $event->getReturnValue();
// solr is configured to give you back a serialized php array
$results = unserialize($response->getRawResponse());
$primaryKeys = array();
foreach($results['response']['docs'] as $doc)
{
$primaryKeys[] = $doc['id'];
}
if(!empty($primaryKeys))
{
$this->results = Doctrine::getTable('myModel')->findByScoredId($primaryKeys);
}
else
{
$this->results = null;
}
Available events
- uvmc_solr.search
- uvmc_solr.commit
- uvmc_solr.add_document
- uvmc_solr.update_document
- uvmc_solr.delete_document
For more informations about those events and the required/optionnals parameters, please check uvmcSolrEventListener.class.php.
Available tasks
Task namespace is uvmc-solr
- reset-index. Reset the entire index of the solr service.
Known issues
Improvements
Credits
- Kudos to Miximum (french) for the inspiration and code snippets :-)