2011-12-13 11:30:45 +01:00
|
|
|
[Elastica](https://github.com/ruflin/Elastica) integration in Symfony2
|
2011-04-08 23:11:46 +02:00
|
|
|
|
|
|
|
## Installation
|
|
|
|
|
|
|
|
### Install elasticsearch
|
|
|
|
|
|
|
|
http://www.elasticsearch.org/guide/reference/setup/installation.html
|
|
|
|
|
|
|
|
### Install Elastica
|
|
|
|
|
|
|
|
#### Download
|
|
|
|
|
2011-12-13 11:49:00 +01:00
|
|
|
**With submodule**
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2011-12-13 11:49:00 +01:00
|
|
|
`git submodule add git://github.com/ruflin/Elastica vendor/elastica`
|
|
|
|
|
|
|
|
**With clone**
|
|
|
|
|
|
|
|
`git clone git://github.com/ruflin/Elastica vendor/elastica`
|
|
|
|
|
|
|
|
**Using the vendors script**
|
|
|
|
|
|
|
|
Add the following lines to your deps file:
|
|
|
|
|
|
|
|
[Elastica]
|
|
|
|
git=git://github.com/ruflin/Elastica.git
|
|
|
|
target=elastica
|
2011-04-08 23:11:46 +02:00
|
|
|
|
|
|
|
#### Register autoloading
|
|
|
|
|
|
|
|
// app/autoload.php
|
|
|
|
|
|
|
|
$loader->registerPrefixes(array(
|
|
|
|
...
|
2011-04-10 23:08:51 +02:00
|
|
|
'Elastica' => __DIR__.'/../vendor/elastica/lib',
|
2011-04-08 23:11:46 +02:00
|
|
|
));
|
|
|
|
|
|
|
|
### Install ElasticaBundle
|
|
|
|
|
2011-12-13 11:30:45 +01:00
|
|
|
Use the master branch with Symfony2 master only, use the 2.0 branch with Symfony2.0.x releases.
|
|
|
|
|
2011-04-08 23:11:46 +02:00
|
|
|
#### Download
|
|
|
|
|
2011-12-13 11:49:00 +01:00
|
|
|
**With submodule**
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
`git submodule add git://github.com/Exercise/FOSElasticaBundle vendor/bundles/FOS/ElasticaBundle`
|
2011-12-13 11:49:00 +01:00
|
|
|
|
|
|
|
**With clone**
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
`git clone git://github.com/Exercise/FOSElasticaBundle vendor/bundles/FOS/ElasticaBundle`
|
2011-12-13 11:49:00 +01:00
|
|
|
|
|
|
|
**With the vendors script**
|
|
|
|
|
|
|
|
Add the following lines to your deps file:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
[FOSElasticaBundle]
|
|
|
|
git=git://github.com/Exercise/FOSElasticaBundle.git
|
|
|
|
target=bundles/FOS/ElasticaBundle
|
2011-12-13 11:49:00 +01:00
|
|
|
|
|
|
|
For the 2.0 branch for use with Symfony2.0.x releases add the following:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
[FOSElasticaBundle]
|
|
|
|
git=git://github.com/Exercise/FOSElasticaBundle.git
|
|
|
|
target=bundles/FOS/ElasticaBundle
|
2011-12-13 11:49:00 +01:00
|
|
|
version=origin/2.0
|
2011-04-08 23:11:46 +02:00
|
|
|
|
2011-12-13 11:49:00 +01:00
|
|
|
Run the vendors script:
|
2011-04-08 23:11:46 +02:00
|
|
|
|
2011-12-13 11:49:00 +01:00
|
|
|
```bash
|
|
|
|
$ php bin/vendors install
|
|
|
|
```
|
2011-04-08 23:11:46 +02:00
|
|
|
#### Register autoloading
|
|
|
|
|
|
|
|
// app/autoload.php
|
|
|
|
|
|
|
|
$loader->registerNamespaces(array(
|
|
|
|
...
|
2013-03-27 18:39:28 +01:00
|
|
|
'FOS' => __DIR__.'/../vendor/bundles',
|
2011-04-08 23:11:46 +02:00
|
|
|
));
|
|
|
|
|
|
|
|
#### Register the bundle
|
|
|
|
|
|
|
|
// app/AppKernel.php
|
|
|
|
|
|
|
|
public function registerBundles()
|
|
|
|
{
|
|
|
|
return array(
|
|
|
|
// ...
|
2013-03-27 18:39:28 +01:00
|
|
|
new FOS\ElasticaBundle\FOSElasticaBundle(),
|
2011-04-08 23:11:46 +02:00
|
|
|
// ...
|
|
|
|
);
|
|
|
|
}
|
2011-04-22 04:34:57 +02:00
|
|
|
|
|
|
|
### Basic configuration
|
|
|
|
|
2011-09-12 18:34:05 +02:00
|
|
|
#### Declare a client
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Elasticsearch client is comparable to a database connection.
|
2011-04-22 04:34:57 +02:00
|
|
|
Most of the time, you will need only one.
|
|
|
|
|
|
|
|
#app/config/config.yml
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-04-22 04:34:57 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
|
|
|
|
#### Declare an index
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Elasticsearch index is comparable to Doctrine entity manager.
|
2011-04-22 04:34:57 +02:00
|
|
|
Most of the time, you will need only one.
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-04-22 04:34:57 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
|
|
|
|
Here we created a "website" index, that uses our "default" client.
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
Our index is now available as a service: `fos_elastica.index.website`. It is an instance of `Elastica_Index`.
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2011-04-22 04:34:57 +02:00
|
|
|
#### Declare a type
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Elasticsearch type is comparable to Doctrine entity repository.
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-04-22 04:34:57 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
types:
|
|
|
|
user:
|
|
|
|
mappings:
|
|
|
|
username: { boost: 5 }
|
|
|
|
firstName: { boost: 3 }
|
|
|
|
lastName: { boost: 3 }
|
2011-09-12 18:34:05 +02:00
|
|
|
aboutMe:
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
Our type is now available as a service: `fos_elastica.index.website.user`. It is an instance of `Elastica_Type`.
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2011-04-22 04:34:57 +02:00
|
|
|
### Populate the types
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
php app/console fos:elastica:populate
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-04-22 19:16:31 +02:00
|
|
|
This command deletes and creates the declared indexes and types.
|
2011-04-22 05:45:26 +02:00
|
|
|
It applies the configured mappings to the types.
|
|
|
|
|
2011-04-22 04:34:57 +02:00
|
|
|
This command needs providers to insert new documents in the elasticsearch types.
|
|
|
|
There are 2 ways to create providers.
|
2011-12-22 00:05:24 +01:00
|
|
|
If your elasticsearch type matches a Doctrine repository or a Propel query, go for the persistence automatic provider.
|
2011-04-22 05:45:26 +02:00
|
|
|
Or, for complete flexibility, go for manual provider.
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
#### Persistence automatic provider
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
If we want to index the entities from a Doctrine repository or a Propel query,
|
2011-04-22 19:16:31 +02:00
|
|
|
some configuration will let ElasticaBundle do it for us.
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-04-22 04:34:57 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
types:
|
|
|
|
user:
|
|
|
|
mappings:
|
2011-06-07 20:13:34 +02:00
|
|
|
username: { boost: 5 }
|
|
|
|
firstName: { boost: 3 }
|
|
|
|
# more mappings...
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
|
|
|
driver: orm # orm, mongodb, propel are available
|
2011-05-09 05:22:51 +02:00
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Three drivers are actually supported: orm, mongodb, and propel.
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
##### Use a custom Doctrine query builder
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-04-22 05:45:26 +02:00
|
|
|
You can control which entities will be indexed by specifying a custom query builder method.
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-05-09 05:22:51 +02:00
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
|
|
|
query_builder_method: createIsActiveQueryBuilder
|
2011-04-22 04:34:57 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Your repository must implement this method and return a Doctrine query builder.
|
|
|
|
|
|
|
|
> **Propel** doesn't support this feature yet.
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
##### Change the batch size
|
|
|
|
|
|
|
|
By default, ElasticaBundle will index documents by paquets of 100.
|
|
|
|
You can change this value in the provider configuration.
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-05-09 05:22:51 +02:00
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
|
|
|
batch_size: 100
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
##### Change the document identifier field
|
|
|
|
|
|
|
|
By default, ElasticaBundle will use the `id` field of your entities as the elasticsearch document identifier.
|
|
|
|
You can change this value in the provider configuration.
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-05-09 05:22:51 +02:00
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
|
|
|
identifier: id
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
#### Manual provider
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
Create a service with the tag "fos_elastica.provider".
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
<service id="acme.search_provider.user" class="Acme\UserBundle\Search\UserProvider">
|
2013-03-27 18:39:28 +01:00
|
|
|
<tag name="fos_elastica.provider" />
|
|
|
|
<argument type="service" id="fos_elastica.index.website.user" />
|
2011-04-22 05:45:26 +02:00
|
|
|
</service>
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
Its class must implement `FOS\ElasticaBundle\Provider\ProviderInterface`.
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Acme\UserBundle\Provider;
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
use FOS\ElasticaBundle\Provider\ProviderInterface;
|
2011-04-22 05:45:26 +02:00
|
|
|
use Elastica_Type;
|
|
|
|
|
|
|
|
class UserProvider implements ProviderInterface
|
|
|
|
{
|
|
|
|
protected $userType;
|
|
|
|
|
|
|
|
public function __construct(Elastica_Type $userType)
|
|
|
|
{
|
|
|
|
$this->userType = $userType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Insert the repository objects in the type index
|
|
|
|
*
|
|
|
|
* @param Closure $loggerClosure
|
|
|
|
*/
|
|
|
|
public function populate(Closure $loggerClosure)
|
|
|
|
{
|
|
|
|
$loggerClosure('Indexing users');
|
|
|
|
|
2012-08-07 00:24:27 +02:00
|
|
|
$document = new \Elastica_Document();
|
|
|
|
$document->setData(array('username' => 'Bob'));
|
|
|
|
$this->userType->addDocuments(array($document));
|
2011-04-22 05:45:26 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
You will find a more complete implementation example in `src/FOS/ElasticaBundle/Doctrine/AbstractProvider.php`.
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
### Search
|
|
|
|
|
|
|
|
You can just use the index and type Elastica objects, provided as services, to perform searches.
|
|
|
|
|
|
|
|
/** var Elastica_Type */
|
2013-03-27 18:39:28 +01:00
|
|
|
$userType = $this->container->get('fos_elastica.index.website.user');
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
/** var Elastica_ResultSet */
|
|
|
|
$resultSet = $userType->search('bob');
|
|
|
|
|
2012-01-25 14:46:15 +01:00
|
|
|
#### Doctrine/Propel finder
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
If your elasticsearch type is bound to a Doctrine entity repository or a Propel query,
|
2011-04-22 05:45:26 +02:00
|
|
|
you can get your entities instead of Elastica results when you perform a search.
|
2011-12-22 00:05:24 +01:00
|
|
|
Declare that you want a Doctrine/Propel finder in your configuration:
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-04-22 05:45:26 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
types:
|
|
|
|
user:
|
|
|
|
mappings:
|
|
|
|
# your mappings
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-05-09 05:22:51 +02:00
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
|
|
|
finder:
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
You can now use the `fos_elastica.finder.website.user` service:
|
2011-04-22 05:45:26 +02:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Finder\TransformedFinder */
|
|
|
|
$finder = $container->get('fos_elastica.finder.website.user');
|
2011-04-22 05:45:26 +02:00
|
|
|
|
|
|
|
/** var array of Acme\UserBundle\Entity\User */
|
|
|
|
$users = $finder->find('bob');
|
|
|
|
|
2011-05-15 03:56:48 +02:00
|
|
|
/** var array of Acme\UserBundle\Entity\User limited to 10 results */
|
|
|
|
$users = $finder->find('bob', 10);
|
|
|
|
|
2011-04-22 05:45:26 +02:00
|
|
|
You can even get paginated results!
|
|
|
|
|
2011-07-05 19:42:14 +02:00
|
|
|
/** var Pagerfanta\Pagerfanta */
|
2011-04-22 05:45:26 +02:00
|
|
|
$userPaginator = $finder->findPaginated('bob');
|
2011-06-07 20:13:34 +02:00
|
|
|
|
2012-08-07 00:30:31 +02:00
|
|
|
You can also get both the Elastica results and the entities together from the finder.
|
|
|
|
YOu can then access the score, highlights etc. from the Elastica_Result whilst
|
|
|
|
still also getting the entity.
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var array of FOS\ElasticaBundle\HybridResult */
|
2012-08-07 00:30:31 +02:00
|
|
|
$hybridResults = $finder->findHybrid('bob');
|
|
|
|
foreach ($hybridResults as $hybridResult) {
|
|
|
|
|
|
|
|
/** var Acme\UserBundle\Entity\User */
|
|
|
|
$user = $hybridResult->getTransformed();
|
|
|
|
|
|
|
|
/** var Elastica_Result */
|
|
|
|
$result = $hybridResult->getResult();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-03 23:16:56 +01:00
|
|
|
##### Index wide finder
|
|
|
|
|
|
|
|
You can also define a finder that will work on the entire index. Adjust your index
|
|
|
|
configuration as per below:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2012-01-03 23:16:56 +01:00
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
finder:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
You can now use the index wide finder service `fos_elastica.finder.website`:
|
2012-01-03 23:16:56 +01:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Finder\MappedFinder */
|
|
|
|
$finder = $container->get('fos_elastica.finder.website');
|
2012-01-03 23:16:56 +01:00
|
|
|
|
|
|
|
// Returns a mixed array of any objects mapped
|
|
|
|
$results = $finder->find('bob');
|
|
|
|
|
2012-01-25 14:46:15 +01:00
|
|
|
#### Repositories
|
|
|
|
|
|
|
|
As well as using the finder service for a particular Doctrine/Propel entity you
|
|
|
|
can use a manager service for each driver and get a repository for an entity to search
|
|
|
|
against. This allows you to use the same service rather than the particular finder. For
|
|
|
|
example:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
|
|
|
|
$repositoryManager = $container->get('fos_elastica.manager.orm');
|
2012-01-25 14:46:15 +01:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Repository */
|
2012-01-25 14:46:15 +01:00
|
|
|
$repository = $repositoryManager->getRepository('UserBundle:User');
|
|
|
|
|
|
|
|
/** var array of Acme\UserBundle\Entity\User */
|
|
|
|
$users = $finder->find('bob');
|
|
|
|
|
|
|
|
You can also specify the full name of the entity instead of the shortcut syntax:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Repository */
|
2012-01-25 14:46:15 +01:00
|
|
|
$repository = $repositoryManager->getRepository('Application\UserBundle\Entity\User');
|
|
|
|
|
|
|
|
> The **2.0** branch doesn't support using `UserBundle:User` style syntax and you must use the full name of the entity. .
|
|
|
|
|
|
|
|
##### Default Manager
|
|
|
|
|
|
|
|
If you are only using one driver then its manager service is automatically aliased
|
2013-03-27 18:39:28 +01:00
|
|
|
to `fos_elastica.manager`. So the above example could be simplified to:
|
2012-01-25 14:46:15 +01:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
|
|
|
|
$repositoryManager = $container->get('fos_elastica.manager');
|
2012-01-25 14:46:15 +01:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Repository */
|
2012-01-25 14:46:15 +01:00
|
|
|
$repository = $repositoryManager->getRepository('UserBundle:User');
|
|
|
|
|
|
|
|
/** var array of Acme\UserBundle\Entity\User */
|
|
|
|
$users = $finder->find('bob');
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
If you use multiple drivers then you can choose which one is aliased to `fos_elastica.manager`
|
2012-01-25 14:46:15 +01:00
|
|
|
using the `default_manager` parameter:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2012-01-25 14:46:15 +01:00
|
|
|
default_manager: mongodb #defauults to orm
|
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
#--
|
|
|
|
|
|
|
|
##### Custom Repositories
|
|
|
|
|
|
|
|
As well as the default repository you can create a custom repository for an entity and add
|
2013-03-27 18:39:28 +01:00
|
|
|
methods for particular searches. These need to extend `FOS\ElasticaBundle\Repository` to have
|
2012-01-25 14:46:15 +01:00
|
|
|
access to the finder:
|
|
|
|
|
|
|
|
```
|
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Acme\ElasticaBundle\SearchRepository;
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
use FOS\ElasticaBundle\Repository;
|
2012-01-25 14:46:15 +01:00
|
|
|
|
|
|
|
class UserRepository extends Repository
|
|
|
|
{
|
|
|
|
public function findWithCustomQuery($searchText)
|
|
|
|
{
|
|
|
|
// build $query with Elastica objects
|
|
|
|
$this->find($query);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
To use the custom repository specify it in the mapping for the entity:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2012-01-25 14:46:15 +01:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
types:
|
|
|
|
user:
|
|
|
|
mappings:
|
|
|
|
# your mappings
|
|
|
|
persistence:
|
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
provider:
|
|
|
|
finder:
|
|
|
|
repository: Acme\ElasticaBundle\SearchRepository\UserRepository
|
|
|
|
|
|
|
|
Then the custom queries will be available when using the repository returned from the manager:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Manager\RepositoryManager */
|
|
|
|
$repositoryManager = $container->get('fos_elastica.manager');
|
2012-01-25 14:46:15 +01:00
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
/** var FOS\ElasticaBundle\Repository */
|
2012-01-25 14:46:15 +01:00
|
|
|
$repository = $repositoryManager->getRepository('UserBundle:User');
|
|
|
|
|
|
|
|
/** var array of Acme\UserBundle\Entity\User */
|
|
|
|
$users = $finder->findWithCustomQuery('bob');
|
|
|
|
|
|
|
|
Alternatively you can specify the custom repository using an annotation in the entity:
|
|
|
|
|
|
|
|
```
|
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Application\UserBundle\Entity;
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
use FOS\ElasticaBundle\Configuration\Search;
|
2012-01-25 14:46:15 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @Search(repositoryClass="Acme\ElasticaBundle\SearchRepository\UserRepository")
|
|
|
|
*/
|
|
|
|
class User
|
|
|
|
{
|
|
|
|
|
|
|
|
//---
|
|
|
|
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2011-06-07 20:13:34 +02:00
|
|
|
### Realtime, selective index update
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
If you use the Doctrine integration, you can let ElasticaBundle update the indexes automatically
|
|
|
|
when an object is added, updated or removed. It uses Doctrine lifecycle events.
|
2011-06-07 20:13:34 +02:00
|
|
|
Declare that you want to update the index in real time:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-06-07 20:13:34 +02:00
|
|
|
clients:
|
|
|
|
default: { host: localhost, port: 9200 }
|
|
|
|
indexes:
|
|
|
|
website:
|
|
|
|
client: default
|
|
|
|
types:
|
|
|
|
user:
|
|
|
|
mappings:
|
|
|
|
# your mappings
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-06-07 20:13:34 +02:00
|
|
|
driver: orm
|
|
|
|
model: Application\UserBundle\Entity\User
|
|
|
|
listener: # by default, listens to "insert", "update" and "delete"
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
Now the index is automatically updated each time the state of the bound Doctrine repository changes.
|
2011-06-07 20:13:34 +02:00
|
|
|
No need to repopulate the whole "user" index when a new `User` is created.
|
|
|
|
|
|
|
|
You can also choose to only listen for some of the events:
|
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
persistence:
|
2011-06-07 20:13:34 +02:00
|
|
|
listener:
|
|
|
|
insert: true
|
|
|
|
update: false
|
|
|
|
delete: true
|
2011-09-12 18:34:05 +02:00
|
|
|
|
2011-12-22 00:05:24 +01:00
|
|
|
> **Propel** doesn't support this feature yet.
|
|
|
|
|
2011-09-12 18:34:05 +02:00
|
|
|
### Advanced elasticsearch configuration
|
|
|
|
|
|
|
|
Any setting can be specified when declaring a type. For example, to enable a custom analyzer, you could write:
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2011-09-12 18:34:05 +02:00
|
|
|
indexes:
|
|
|
|
doc:
|
2011-12-19 13:39:20 +01:00
|
|
|
settings:
|
|
|
|
index:
|
|
|
|
analysis:
|
|
|
|
analyzer:
|
|
|
|
my_analyzer:
|
2011-09-12 18:34:05 +02:00
|
|
|
type: custom
|
|
|
|
tokenizer: lowercase
|
|
|
|
filter : [my_ngram]
|
2011-12-19 13:39:20 +01:00
|
|
|
filter:
|
|
|
|
my_ngram:
|
2011-09-12 18:34:05 +02:00
|
|
|
type: "nGram"
|
|
|
|
min_gram: 3
|
|
|
|
max_gram: 5
|
|
|
|
types:
|
|
|
|
blog:
|
|
|
|
mappings:
|
|
|
|
title: { boost: 8, analyzer: my_analyzer }
|
2011-12-28 23:08:47 +01:00
|
|
|
|
|
|
|
### Overriding the Client class to suppress exceptions
|
|
|
|
|
2012-01-25 14:46:15 +01:00
|
|
|
By default, exceptions from the Elastica client library will propagate through
|
2011-12-28 23:08:47 +01:00
|
|
|
the bundle's Client class. For instance, if the elasticsearch server is offline,
|
|
|
|
issuing a request will result in an `Elastica_Exception_Client` being thrown.
|
|
|
|
Depending on your needs, it may be desirable to suppress these exceptions and
|
|
|
|
allow searches to fail silently.
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
One way to achieve this is to override the `fos_elastica.client.class` service
|
2011-12-28 23:08:47 +01:00
|
|
|
container parameter with a custom class. In the following example, we override
|
|
|
|
the `Client::request()` method and return the equivalent of an empty search
|
|
|
|
response if an exception occurred.
|
|
|
|
|
|
|
|
```
|
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace Acme\ElasticaBundle;
|
|
|
|
|
2013-03-27 18:39:28 +01:00
|
|
|
use FOS\ElasticaBundle\Client as BaseClient;
|
2011-12-28 23:08:47 +01:00
|
|
|
|
|
|
|
class Client extends BaseClient
|
|
|
|
{
|
|
|
|
public function request($path, $method, $data = array())
|
|
|
|
{
|
|
|
|
try {
|
|
|
|
return parent::request($path, $method, $data);
|
|
|
|
} catch (\Elastica_Exception_Abstract $e) {
|
|
|
|
return new \Elastica_Response('{"took":0,"timed_out":false,"hits":{"total":0,"max_score":0,"hits":[]}}');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
```
|
2012-07-26 12:12:48 +02:00
|
|
|
|
2013-03-07 23:10:54 +01:00
|
|
|
### Example of Advanced Query
|
2012-07-26 12:12:48 +02:00
|
|
|
|
2013-03-07 23:10:54 +01:00
|
|
|
If you would like to perform more advanced queries, here is one example using
|
|
|
|
the snowball stemming algorithm.
|
2012-07-26 12:12:48 +02:00
|
|
|
|
2013-03-07 23:10:54 +01:00
|
|
|
It searches for Article entities using `title`, `tags`, and `categoryIds`.
|
|
|
|
Results must match at least one specified `categoryIds`, and should match the
|
|
|
|
`title` or `tags` criteria. Additionally, we define a snowball analyzer to
|
|
|
|
apply to queries against the `title` field.
|
2012-07-26 12:12:48 +02:00
|
|
|
|
|
|
|
```php
|
2013-03-27 18:39:28 +01:00
|
|
|
$finder = $this->container->get('fos_elastica.finder.website.article');
|
2012-07-26 12:12:48 +02:00
|
|
|
$boolQuery = new \Elastica_Query_Bool();
|
|
|
|
|
|
|
|
$fieldQuery = new \Elastica_Query_Text();
|
|
|
|
$fieldQuery->setFieldQuery('title', 'I am a title string');
|
|
|
|
$fieldQuery->setFieldParam('title', 'analyzer', 'my_analyzer');
|
|
|
|
$boolQuery->addShould($fieldQuery);
|
|
|
|
|
|
|
|
$tagsQuery = new \Elastica_Query_Terms();
|
|
|
|
$tagsQuery->setTerms('tags', array('tag1', 'tag2'));
|
|
|
|
$boolQuery->addShould($tagsQuery);
|
|
|
|
|
|
|
|
$categoryQuery = new \Elastica_Query_Terms();
|
2013-03-07 23:10:54 +01:00
|
|
|
$categoryQuery->setTerms('categoryIds', array('1', '2', '3'));
|
|
|
|
$boolQuery->addMust($categoryQuery);
|
2012-07-26 12:12:48 +02:00
|
|
|
|
|
|
|
$data = $finder->find($boolQuery);
|
|
|
|
```
|
|
|
|
|
|
|
|
Configuration:
|
|
|
|
|
2013-03-07 23:10:54 +01:00
|
|
|
```yaml
|
2013-03-27 18:39:28 +01:00
|
|
|
fos_elastica:
|
2012-07-26 12:12:48 +02:00
|
|
|
clients:
|
2013-03-07 23:10:54 +01:00
|
|
|
default: { host: localhost, port: 9200 }
|
2012-07-26 12:12:48 +02:00
|
|
|
indexes:
|
|
|
|
site:
|
|
|
|
settings:
|
|
|
|
index:
|
|
|
|
analysis:
|
|
|
|
analyzer:
|
|
|
|
my_analyzer:
|
|
|
|
type: snowball
|
|
|
|
language: English
|
|
|
|
types:
|
|
|
|
article:
|
|
|
|
mappings:
|
|
|
|
title: { boost: 10, analyzer: my_analyzer }
|
2013-03-07 23:10:54 +01:00
|
|
|
tags:
|
2012-07-26 12:12:48 +02:00
|
|
|
categoryIds:
|
|
|
|
persistence:
|
2013-03-07 23:10:54 +01:00
|
|
|
driver: orm
|
2012-07-26 12:12:48 +02:00
|
|
|
model: Acme\DemoBundle\Entity\Article
|
|
|
|
provider:
|
|
|
|
finder:
|
|
|
|
```
|