Good afternoon, I want to submit my symfony 2 bundle to automatically synchronize the Doctrine entity in Solr and the subsequent search. The bundle is designed to work with Solr at the Doctrine entity level and avoids writing low-level solr queries. The installation process and detailed documentation can be viewed on github .
The main (not all) search capabilities of the standard Solr query parser are implemented :
Support for SuggestComponent is also implemented .
After installation, you need to configure a bundle in config.yml to get started. An example of a minimal configuration of a bundle:
mdiyakov_doctrine_solr: indexed_entities: page: class: AppBundle\Entity\Page schema: page config: - { name: type, value: page } schemes: page: document_unique_field: { name: 'uid' } config_entity_fields: - { config_field_name: 'type', document_field_name: 'type', discriminator: true } fields: - { entity_field_name: 'id', document_field_name: 'entity_id', field_type: int, entity_primary_key: true } - { entity_field_name: 'textField', document_field_name: 'text', priority: 100, suggester: true }
As a result, after each creation, the updates of the "AppBundle \ Entity \ Page" entities will be indexed by the id and textField fields, as well as the type configuration field. If an entity instance is deleted, the corresponding solr document will be deleted.
The "schemes" section describes indexing schemes. The indexing scheme includes a description of the fields of the entity (fields), the configuration fields (config_entity_fields) that should be indexed in solr. And also the "document_unique_field" indicating a unique field for the schemes.xml in solr. In addition, there is an optional client field in case you need to use several solr core for different indexing schemes (more on this here ). In fact, each scheme in the schemes reflects a specific solr core.
The configuration field is a field that is specified in the "indexed_entities" section within the framework of the entity config. It can be used to index the parameters specified in parameters.yml, for example:
.... class: AppBundle\Entity\Page schema: page config: - { name: app_version, value: %app_version% } - { name: host, value: %host% } ... ....
For each indexed entity, at least one configuration field with a unique value relative to all indexed entities designated as discriminator must be specified: true in schemes. For example:
mdiyakov_doctrine_solr: indexed_entities: page: class: AppBundle\Entity\Article schema: page config: - { name: type, value: article } news: class: AppBundle\Entity\News schema: page config: - { name: type, value: news } schemes: page: ... config_entity_fields: - { config_field_name: 'type', document_field_name: 'discriminator', discriminator: true }
Since and AppBundle \ Entity \ Article and AppBundle \ Entity \ News use the same "page" scheme then acc. their primary key uniqueness is lost there may be News and Article with the same id. To avoid ambiguity, a configuration field is used that is used as a discriminator, the value of which is added to the primary key entity and the result is recorded in a unique document field.
It is also possible to set filters for indexed entities used before the entity is indexed in solr. Depending on the result of the filter, an entity can be indexed, deleted, or skipped during indexing. Example:
indexed_entities: page: class: AppBundle\Entity\Page ... filters: [ big_id, published, ... ] news: class: AppBundle\Entity\News ... filters: [ published, ... ] schemes: .... filters: fields: big_id: { entity_field_name: "id", entity_field_value: 3, operator: ">=" } published: { entity_field_name: "published", entity_field_value: true, operator: "=" }
Corresponding if after Page or News has been created and for example the field "published" = false, then the indexing will be skipped and nothing will be written to solr.
If the Page or News were updated and for example the field "published" = false, then the solr document corresponding to this entity instance will be deleted in solr
The same is true for the big_id filter, if the value of the id field is <3. "big_id" and "published" are arbitrary names for filters, which can be anything. There is also the possibility of a task symfony service as a filter that is applied to an entity instance and not to a separate field, details are here.
For successful indexing, the conditions for all filters must be met.
An entity is indexed every time $ em-> flush is executed and implemented via https://symfony.com/doc/current/bundles/DoctrineBundle/entity-listeners.html
In the case when you need to perform primary indexing for all entities in the database, the console command is implemented:
app/console doctrine-solr:index
Details of her work and arguments can be found on github .
After the configuration is set and indexing is done, you can search both within the framework of a separate entity and within the framework of the scheme. Example:
// MyController //... // @var \Mdiyakov\DoctrineSolrBundle\Finder\ClassFinder $finder $finder = $this->get('ds.finder')->getClassFinder(Article::class); /** @var Article[] $searchResults */ $searchResults = $finder->findSearchTermByFields($searchTerm, ['title']);
The result will be an array consisting only of Article :: class.
If the scheme is used by several entities, for example:
indexed_entities: page: class: AppBundle\Entity\Article schema: page ... news: class: AppBundle\Entity\News schema: page ... ...
then you can search for all entities using this scheme:
$schemaFinder = $this->get('ds.finder')->getSchemaFinder('page'); $schemaFinder->addSelectClass(Article::class); $schemaFinder->addSelectClass(News::class); /** @var object[] **/ $result = $schemaFinder->findSearchTermByFields($searchTerm, ['title', 'category']);
The result will be an array consisting of Article and News instances sorted in acc. with relevance.
Read more about search methods here.
This is an introductory article that does not fully describe all the possibilities. If you are interested in the bundle, here are a couple of links to quickly navigate through the rest of the bundle features:
UPD: Added support for symfony 3 and php 7
Source: https://habr.com/ru/post/350134/
All Articles