Name: SolrBundle
Owner: PwC Experience Center
Description: Solr-Integration into Symfony2 and Doctrine2
Created: 2015-10-23 11:02:13.0
Updated: 2015-10-23 11:02:14.0
Pushed: 2015-10-23 11:12:29.0
Homepage: http://floriansemm.github.io/SolrBundle
Size: 1071
Language: PHP
GitHub Committers
User | Most Recent Commit | # Commits |
---|
Other Committers
User | Most Recent Commit | # Commits |
---|
This Bundle provides a simple API to index and query a Solr Index.
And do not forget to join the Gitter chat
Installation is a quick (I promise!) 3 step process:
This bundle is available on Packagist. You can install it using Composer:
mposer require floriansemm/solr-bundle
Finally, enable the bundle in the kernel
p
pp/AppKernel.php
ic function registerBundles()
$bundles = array(
// ...
new FS\SolrBundle\FSSolrBundle(),
);
p/config/config.yml
olr:
endpoints:
core1:
host: host
port: 8983
path: /solr/core1
core: corename
timeout: 5
core2:
host: host
port: 8983
path: /solr/core2
core: corename
timeout: 5
With this config you can setup two cores: core1
and core2
. See section Specify cores
for more information.
To put an entity to the index, you must add some annotations to your entity:
our Entity
...
FS\SolrBundle\Doctrine\Annotation as Solr;
olr\Document(repository="Full\Qualified\Class\Name")
RM\Table()
s Post
/**
* @Solr\Id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* @Solr\Field(type="string")
*
* @ORM\Column(name="title", type="string", length=255)
*/
private $title = '';
/**
*
* @Solr\Field(type="string")
*
* @ORM\Column(name="text", type="text")
*/
private $text = '';
**
* @Solr\Field(type="date")
*
* @ORM\Column(name="created_at", type="datetime")
*/
private $created_at = null;
Currently is a basic set of types implemented.
It is possible to use custom field types (schema.xml).
In some cases a entity should not be index. For this you have the SynchronizationFilter
Annotation.
Solr\Document
Solr\SynchronizationFilter(callback="shouldBeIndex")
s SomeEntity
/**
* @return boolean
*/
public function shouldBeIndex()
{
// put your logic here
}
The callback property specifies an callable function, which decides whether the should index or not.
It is possible to specify a core dedicated to a document
Solr\Document(index="core0")
s SomeEntity
// ...
All documents will be indexed in the core core0
. If your entities/document have different languages then you can setup
a callback method, which returns the preferred core for the entity.
Solr\Document(indexHandler="indexHandler")
s SomeEntity
public function indexHandler()
{
if ($this->language == 'en') {
return 'core0';
}
}
Each core must setup up in the config.yml under endpoints
. If you leave the index
or indexHandler
property empty,
then a default core will be used (first in the endpoints
list). To index a document in all cores use *
as index value:
r\Document(index="*")
Solr comes with a set of predefined field-name/field-types mapping:
For details have a look into your schema.xml.
So if you have an entity with a property “category”, then you don't need a type-declaration in the annotation:
Solr\Field
ORM\Column(name="category", type="text")
ate $category = '';
The field has in this case automaticaly the type “general_text”.
If you persist this entity, it will put automatically to the index. Update and delete happens automatically too.
To query the index you have to call some services.
ry = $this->get('solr.client')->createQuery('AcmeDemoBundle:Post');
ry->addSearchTerm('title', 'my title');
ult = $query->getResult();
The $result array contains all found entities. The solr-service does all mappings from SolrDocument to your entity for you.
The pervious examples have queried only the field 'title'. You can also query all fields with a string.
ry = $this->get('solr.client')->createQuery('AcmeDemoBundle:Post');
ry->queryAllFields('my title');
ult = $query->getResult();
To narrow the mapping, you can use the addField()
method.
ry = $this->get('solr.client')->createQuery('AcmeDemoBundle:Post');
ry->addSearchTerm('title', 'my title');
ry->addField('id');
ry->addField('text');
ult = $query->getResult();
In this case only the fields id and text will be mapped (addField()), so title and created_at will be empty. If nothing was found $result is empty.
The result contains by default 10 rows. You can increase this value:
ry->setRows(1000000);
HydrationMode tells the Bundle how to create an entity from a document.
FS\SolrBundle\Doctrine\Hydration\HydrationModes::HYDRATE_INDEX
- use only the data from solrFS\SolrBundle\Doctrine\Hydration\HydrationModes::HYDRATE_DOCTRINE
- merge the data from solr with the entire doctrine-entityWith a custom query:
ry = $this->get('solr.client')->createQuery('AcmeDemoBundle:Post');
ry->setHydrationMode($mode)
With a custom document-repository you have to set the property $hydrationMode
itself:
ic function find($id)
$this->hydrationMode = HydrationModes::HYDRATE_INDEX;
return parent::find($id);
To index your entities manually, you can do it the following way:
s->get('solr.client')->addDocument($entity);
s->get('solr.client')->updateDocument($entity);
s->get('solr.client')->removeDocument($entity);
removeDocument()
requires that the entity-id is set.
If you specify your own repository you must extend the FS\SolrBundle\Repository\Repository
class. The usage is the same
like Doctrine-Repositories:
epository = $this->get('solr.client')->getRepository('AcmeDemoBundle:Post');
ult = $myRepository->mySpecialFindMethod();
If you haven't declared a concrete repository in your entity and you calling $this->get('solr.client')->getRepository('AcmeDemoBundle:Post')
, you will
get an instance of FS\SolrBundle\Repository\Repository
.
There are two commands with this bundle:
solr:index:clear
- delete all documents in the indexsolr:synchronize
- synchronize the db with the index