DoctrineSolrBundle-Symfony2 / 3でのSolrベースのDoctrineエンティティ検索

DoctrineSolrBundle



こんにちは、SolrのDoctrineエンティティを自動的に同期して検索するためのsymfony 2バンドルを紹介したいと思います。 このバンドルは、DoctrineエンティティレベルでSolrと連携するように設計されており、solrで低レベルのクエリを記述しないようにします。 インストールプロセスと詳細なドキュメントはgithubで見ることができます。







特徴



標準のSolr要求パーサーの検索の主な(すべてではない)機能が実装されています









SuggestComponentのサポートも実装されています。







構成例



インストール後、開始するには、config.ymlでバンドルを設定する必要があります。 最小バンドル構成の例:







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 }
      
      





その結果、各作成後、「AppBundle \ Entity \ Page」エンティティ、「id」および「textField」フィールド、および「type」構成フィールドが更新されます。 エンティティインスタンスが削除されると、対応するsolrドキュメントが削除されます。







「スキーム」セクションでは、インデックススキームについて説明します。 インデックススキームには、solrでインデックスを作成する必要があるエンティティフィールド(フィールド)、構成フィールド(config_entity_fields)の説明が含まれます。 また、solrのschemes.xmlの一意のフィールドを示す「document_unique_field」。 さらに、異なるインデックススキームに複数のsolrコアを使用する必要がある場合は、オプションのクライアントフィールドがあります(これについては、 こちらをご覧ください )。 実際、スキームの各回路は特定のsolrコアを反映しています。







構成フィールドは、エンティティ構成内の「indexed_entities」セクションで設定されるフィールドです。 parameters.ymlで指定されたパラメーターにインデックスを付けるために使用できます。例えば:







 .... class: AppBundle\Entity\Page schema: page config: - { name: app_version, value: %app_version% } - { name: host, value: %host% } ... ....
      
      





インデックス付きエンティティごとに、少なくとも1つの構成フィールドを、すべてのインデックス付きエンティティに関連する一意の値で指定する必要があります。識別フィールドとして指定されます。スキームではtrueです。 例:







 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 }
      
      





なぜなら AppBundle \ Entity \ ArticleとAppBundle \ Entity \ Newsの両方で、それぞれ同じ「ページ」スキームが使用されます。 主キーの一意性は失われます ニュースと記事は同じIDで存在する場合があります。 あいまいさを避けるために、識別フィールドとして使用される構成フィールドが設定され、その値がエンティティの主キーに追加され、結果が一意のドキュメントフィールドに書き込まれます。







エンティティがsolrでインデックス付けされる前に使用されるインデックス付きエンティティにフィルタを設定することもできます。 フィルターの結果に応じて、インデックス作成中にエンティティをインデックス化、削除、またはスキップできます。 例:







 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: "=" }
      
      





Acc。 ページまたはニュースが作成れた後、たとえば「published」フィールドがfalseの場合、インデックス作成はスキップされ、solrには何も書き込まれません。







PageまたはNewsが更新され 、たとえば「published」= falseフィールドの場合、このエンティティインスタンスに対応するsolrドキュメントはsolrで削除されます







値がid <3の場合、big_idフィルターについても同様です。「big_id」および「published」はフィルターの任意の名前であり、任意の名前を使用できます。 symfonyサービスを、個別のフィールドではなく、エンティティインスタンスに適用されるフィルターとしてタスクすることも可能です。詳細はこちら

インデックス作成を成功させるには、すべてのフィルターの条件を満たしている必要があります。







索引付け



エンティティのインデックス作成は、$ em-> flushが実行され、 https://symfony.com/doc/current/bundles/DoctrineBundle/entity-listeners.htmlを通じて実装されるたびにトリガーされます







データベース内のすべてのエンティティに対してプライマリインデックスを実行する必要がある場合、コンソールコマンドが実装されます。







 app/console doctrine-solr:index
      
      





彼女の仕事と議論の詳細はgithubで見つけることができます。







検索例:



構成が設定され、インデックス作成が完了したら、別のエンティティとスキーム内の両方で検索できます。 例:







 // MyController //... // @var \Mdiyakov\DoctrineSolrBundle\Finder\ClassFinder $finder $finder = $this->get('ds.finder')->getClassFinder(Article::class); /** @var Article[] $searchResults */ $searchResults = $finder->findSearchTermByFields($searchTerm, ['title']);
      
      





結果は、Article ::クラスのみで構成される配列になります。







たとえば、スキーマが複数のエンティティで使用されている場合:







  indexed_entities: page: class: AppBundle\Entity\Article schema: page ... news: class: AppBundle\Entity\News schema: page ... ...
      
      





次に、このスキームを使用してすべてのエンティティを検索できます。







 $schemaFinder = $this->get('ds.finder')->getSchemaFinder('page'); $schemaFinder->addSelectClass(Article::class); $schemaFinder->addSelectClass(News::class); /** @var object[] **/ $result = $schemaFinder->findSearchTermByFields($searchTerm, ['title', 'category']);
      
      





結果は、それぞれソートされたArticleおよびNewsインスタンスで構成される配列になります。 関連性。







検索方法の詳細については、 こちらをご覧ください。







おわりに



これはすべての可能性を完全には説明していない入門記事です。 バンドルに興味がある場合は、バンドルの残りの機能にすばやくジャンプするためのリンクがいくつかあります。









UPD: Symfony 3およびPHP 7のサポートを追加しました








All Articles