Searcher は、フレームワークに依存しない検索クエリ ビルダーです。検索クエリは基準を使用して作成され、MySQL、MongoDB、ElasticSearch、ファイル、その他任意のものに対して実行できます。最新バージョンは PHP 7 のみをサポートしています。 Humbug でもテストされました
さまざまな基準に基づいて何かを検索するコードを見たことがありますか?かなり混乱する可能性があります。 20 個のフィールドを含むフォームがあり、そのすべてが検索条件に何らかの影響を与えていると想像してください。フォーム全体を何らかのサービスに渡して、すべてを 1 か所で解析させるのは得策ではありません。このライブラリのおかげで、クエリ条件の構築を複数の小さなクラスに分担できます。フィルターごとに 1 つのクラス。 Criteria
ごとに 1 つのCriteriaBuilder
。こうすることで、 CriteriaBuilder
内では 1 つのCriteria
のみを考慮することになり、より読みやすく、保守しやすくなります。後で、異なるCriteriaBuilder
や異なるデータベースを使用できる異なるSearchingContext
を使用して、異なる検索にまったく同じCriteria
使用することができます。 FinderSearchingContext
のおかげで、サーチャーを使用してシステム上のファイルを検索することもできます。
完全なドキュメントは http://searcher.rtfd.io/ にあります。
ターミナルに次のように入力すると、composer 経由でライブラリをインストールできます。
$コンポーザーにはkrzysztof-gzocha/searcherが必要です
Symfony との統合はSearcherBundleで行われます
CriteriaBuilder
- 単一のCriteria
の新しい条件を構築します。
CriteriaBuilder
に渡されるCriteria
-model。何とか水分補給するだけなので重宝します。 Criteria は内部に複数のフィールドを保持でき、それらのすべて (または一部) がCriteriaBuilder
内で使用される可能性があります。
SearchingContext
- 単一の検索のコンテキスト。このサービスは、構築されたクエリから結果を取得する方法を知っている必要があり、 QueryBuilder
と呼ばれるものを保持しますが、機能するサービスであれば何でも構いません。これは、検索とデータベースの間の抽象化レイヤーです。 Doctrine の ORM、ODM、Elastica、ファイルなどにはさまざまなコンテキストがあります。コンテキストがない場合は、コンテキストを実装できます。それは難しいことではありません。
Searcher
- CriteriaBuilder
のコレクションを保持し、 Criteria
適切なCriteriaBuilder
に渡します。
年齢がフィルターされた範囲内にある人を検索したいとします。この例では Doctrine の QueryBuilder を使用するため、 QueryBuilderSearchingContext
使用し、 DoctrineORMQueryBuilder
とのみ対話するようにCriteriaBuidler
で指定しますが、Doctrine のみを使用する必要はないことに注意してください。
まず最初に、最小年齢と最大年齢の値を保持するクラスであるAgeRangeCriteria
を作成する必要があります。ここにはデフォルトのCriteria
がすでに実装されています。
class AgeRangeCriteria は CriteriaInterface{private $minimalAge;private $maximalAge;/** * のみ必須のメソッドです。 * が true を返す場合、それは CriteriaBuilder の一部に渡されます。 */public function shouldBeApplied(): bool{return null !== $this->minimalAge && null !== $this->maximalAge; }// ゲッター、セッターなど何でも}
2 番目のステップでは、このモデルに課す必要がある条件を指定します。そのため、 AgeRangeCriteriaBuilder
を作成する必要があります。
class AgeRangeCriteriaBuilder は CriteriaBuilderInterface{public function buildCriteria(CriteriaInterface $criteria,SearchingContextInterface $searchingContext) {$searchingContext->getQueryBuilder() を実装します。 ->andWhere('e.age >= :minimalAge') ->andWhere('e.age <= :maximalAge') ->setParameter('minimalAge', $criteria->getMinimalAge()) ->setParameter('maximalAge', $criteria->getMaximalAge()); }パブリック関数 allowedCriteria(CriteriaInterface $criteria): bool{AgeRangeCriteria の $criteria インスタンスを返します。 }/** * AbstractORMCriteriaBuilder から拡張する場合は、このメソッドをスキップできます。 */public function supportSearchingContext(SearchingContextInterface $searchingContext): bool{QueryBuilderSearchingContext の $searchingContext インスタンスを返します。 } }
次のステップでは、 Criteria
とCriteriaBuidler
両方のコレクションを作成する必要があります。
$builders = new CriteriaBuilderCollection();$builders->addCriteriaBuilder(new AgeRangeCriteriaBuilder());$builders->addCriteriaBuilder(/** 残りのビルダー */);
$ageRangeCriteria = new AgeRangeCriteria();// 検索する前にモデルを設定する必要があります$ageRangeCriteria->setMinimalAge(23);$ageRangeCriteria->setMaximalAge(29);$criteria = new CriteriaCollection();$criteria->addCriteria( $ageRangeCriteria);$criteria->addCriteria(/**残りの基準 */);
ここで、 SearchingContext
を作成し、Doctrine ORM から取得した QueryBuilder をそれに設定したいと思います。
$context = 新しい QueryBuilderSearchingContext($queryBuilder);$searcher = 新しい Searcher($builders, $context);$searcher->search($criteriaCollection); // やった、結果が出た!
通過可能なオブジェクトまたは配列を期待しているときに QueryBuilder がnull
を返す可能性が少しでもある場合は、通常のSearcher
クラスの代わりにWrappedResultsSearcher
を使用できます。これはSearcher
とまったく同じように動作しますが、 ResultCollection
返します。これは配列またはTraversable
でのみ機能し、result が単なるnull
の場合でもコードは機能します。これは次のようになります。
$searcher = new WrappedResultsSearcher(new Searcher($builders, $context));$results = $searcher->search($criteriaCollection); // ResultCollectionforeach のインスタンス ($results as $result) {// 動作します!}foreach ($results->getResults() as $result) {// ResultCollection には getResults() メソッドがあるため、これも動作します!}
結果を並べ替えるには、すでに実装されているCriteria
を利用できます。最初から実装する必要はありません。そのためにはCriteriaBuilder
実装する必要があることに注意してください (この機能はまだ開発中です)。 結果を並べ替えたいとします。そのためには CriteriaBuidler に値p.id
必要ですが、それをpid
としてエンドユーザーに表示したいとします。これ以上にシンプルなことはありません。 OrderByCriteria を作成する方法は次のとおりです。
$mappedFields = ['pid' => 'p.id', 'valueForUser' => 'valueForBuilder'];$criteria = new MappedOrderByAdapter(new OrderByCriteria('pid'),$mappedFields);// $criteria->getMappedOrderBy () = 'p.id'// $criteria->getOrderBy() = 'pid'
もちろん、 MappedOrderByAdapter
使用する必要はありません。 OrderByCriteria
だけを使用することもできますが、ユーザーは並べ替えにどのフィールドが使用されているかを正確に知ることができます。
ページネーションのCriteria
も実装されているため、これを実行する必要はありませんが、それを利用して実際のページネーションを行うCriteriaBuilder
実装する必要があることに注意してください (この機能は開発中です)。エンドユーザーにページの変更を許可したいが、ページごとの項目数は許可しないとします。次のコード例を使用できます。
$criteria = new ImmutablePaginationAdapter( new PaginationCriteria($page = 1, $itemsPerPage = 50) );// $criteria->setItemsPerPage(250); <- ユーザーは変更を試みることができます// $criteria->getItemsPerPage() = 50 <- しかし実際には変更できません// $criteria->getPage() = 1
もちろん、ユーザーがページごとの項目数を変更できるようにしたい場合は、 ImmutablePaginationAdapter
をスキップしてPaginationCriteria
だけを使用することもできます。
すべてのアイデアとプル リクエストは歓迎され、高く評価されています :) 使用方法に問題がある場合は、ためらわずに問題を作成してください。問題を一緒に解決できます。
テストを実行するコマンド: composer test
。
すべての単体テストは、Mutation Score Indicator を 100% または 100% に近づけることを目的として、突然変異テスト用の Padric/humbug ライブラリを使用してテストされます。
突然変異テストを実行するには、humbug をインストールし、メイン ディレクトリでhumbug
実行する必要があります。出力はhumbuglog.txt
に保存する必要があります。
アルファベット順
https://github.com/chkris
https://github.com/pawelhertman
https://github.com/ustrugany
https://github.com/wojciech-olszewski
ライセンス: MIT
著者: クシシュトフ グゾカ