icanboogie / facets
简化了实现分面搜索。
Requires
- php: >=7.2
- icanboogie/activerecord: ^5.0
Requires (Dev)
- icanboogie/event: ^4.0
- phpunit/phpunit: ^8.5
README
与 icanboogie/activerecord 包一起,此库简化了实现分面搜索。库使得解析查询字符串(单词袋)、使用序列化标准值(如集合(例如“1|2|3”)或区间(例如“1990..2010”)变得特别容易,并可以检索满足条件数组记录。
检索满足条件的记录
可以使用一个 BasicFetcher 实例来检索满足一系列条件的记录。该 fetcher 负责构建查询和检索匹配记录所需的各个步骤。这些步骤可以总结如下
- 解析指定的修饰符并提取条件、偏移量、限制、排序和查询字符串。
- 构建初始查询。
- 调用标准来修改查询。
- 使用条件修改查询。
- 计算与查询匹配的记录总数。
- 使用排序修改查询。
- 使用偏移量和限制修改查询。
- 检索与查询匹配的记录。
- 调用标准来修改记录。
- 返回一个包含记录的 RecordCollection 实例。
以下示例演示了如何使用 BasicFetcher 实例检索被归类在“音乐”类别中,且在2010年至2014年间发布的在线文章。最多可以检索10篇文章,并且它们按最近发布的顺序排列。
<?php use ICanBoogie\ActiveRecord; use ICanBoogie\Facets\Fetcher\BasicFetcher; $model = ActiveRecord\get_model('articles'); $fetcher = new BasicFetcher($model); $records = $fetcher([ 'year' => "2010..2014", 'is_online' => true, 'category' => "music", 'order' => "-date", 'limit' => 10 ]);
使用模型检索记录
此包向 Model 实例添加了 fetch_records()
和 fetch_record()
方法,允许直接从模型中检索记录,而无需构建 BasicFetcher 实例。
$records = $model->fetch_records([ 'year' => "2010..2014", 'is_online' => true, 'category' => "music", 'order' => "-date", 'limit' => 10 ]);
请注意,可以使用方法的第二个参数获取用于检索记录的 BasicFetcher 实例。
$records = $model->fetch_records($conditions, $fetcher);
感兴趣的属性
记录返回后,以下属性可能值得关注
query_string
:从q
修饰符解析的 QueryString 实例。conditions
:用于过滤检索记录的条件数组。order
:检索记录的顺序,由order
修饰符定义。count
:在应用偏移量和限制之前与查询匹配的记录数。
修改检索的记录
检索到的记录以 RecordCollection 实例的形式返回,此类实例可以用来触发类 RecordCollection\AlterEvent 的 alter
事件。事件钩子可以使用此事件来修改集合中的记录,例如,使用单个查询检索与一系列文章相关联的图像。
<?php use ICanBoogie\Facets\RecordCollection; $records = $fetcher(…); new RecordCollection\AlterEvent($records);
使用 CriterionList
实例检索记录
如果您觉得使用 BasicFetcher 实例不足以构成挑战,您可以使用 CriterionList 并自行完成所有艰巨的工作。
<?php use ICanBoogie\Facets\CriterionList; use App\Modules\Vehicles; $criterion_list = new CriterionList([ 'family' => Vehicles\Families\FamilyCriterion::class, 'brand' => Vehicles\Brands\BrandCriterion::class, 'category' => Vehicles\Categories\CategoryCriterion::class, 'color' => Vehicles\Colors\ColorCriterion::class, 'energy' => Vehicles\Energies\EnergyCriterion::class, 'engine' => Vehicles\Engines\EngineCriterion::class, 'doors' => Vehicles\DoorsCriterion::class, 'year' => Vehicles\YearCriterion::class, 'price' => Vehicles\PriceCriterion::class ]); $modifiers = $_GET + [ 'q' => null, // reserved keyword for query string 'order' => null // reserved keyword for records order ]; if ($modifiers['q']) { $q = $criterion_list->parse_query_string($modifiers['q']); echo "The following words were matched: " . implode(' ', $q->matched) . '<br />'; echo "The following words were not matched: " . implode(' ', $q->not_matched) . '<br />'; // we choose to _OR_ criterion values $modifiers += array_map(function($v) { return implode('|', $v); }, $q->matches); } # # Parameters are passed by reference, $values and $query are likely to be modified. # $conditions = []; $criterion_list ->alter_conditions($conditions, $modifiers) ->alter_query($query) ->alter_query_with_conditions($query, $conditions); if ($modifiers['order']) { $criterion_list->alter_query_with_order($query, $modifiers['order']); } $count = $query->count; // count all the records matching the query $records = $query->limit(20)->all; // fetch a maximum of 20 records
准则值
准则值通常在 CriterionList 实例使用值修改查询时创建。如果值的键与准则标识符匹配,则调用该准则的 parse_value() 来检索一个 准则值,这可能是一个确切的值,也可能是如果值是复杂的情况下,例如 区间 或 集合,则可能是一个 CriterionValue 实例。
产生的 准则值 用于在 alter_query_with_value() 期间修改查询。区间值 导致 BETWEEN ? AND ?
,=> ?
和 <= ?
条件;而 集合值 导致 IN(?)
条件。
区间值
区间值由 IntervalCriterionValue 实例表示。当指定为字符串时,使用两个点 ..
来分隔下界和上界。可以使用以下任何语句创建区间值:
<?php use ICanBoogie\Facets\CriterionValue\IntervalCriterionValue; $value = IntervalCriterionValue::from('123..456'); // between 123 and 456 $value = IntervalCriterionValue::from('123..'); // >= 123 $value = IntervalCriterionValue::from('..456'); // <= 456 $value = IntervalCriterionValue::from([ 'min' => '123', 'max' => '456' ]); // between 123 and 456 $value = IntervalCriterionValue::from([ 'min' => '123', 'max' => null ]); // >= 123 $value = IntervalCriterionValue::from([ 'min' => null, 'max' => '456' ]); // <= 456 $value = new IntervalCriterionValue(123, 456); // between 123 and 456 $value = new IntervalCriterionValue(null, 456); // >= 123 $value = new IntervalCriterionValue(123, null); // <= 456
IntervalCriterionValue 实例也可以用作字符串。
<?php use ICanBoogie\Facets\CriterionValue\IntervalCriterionValue; echo new IntervalCriterionValue(123, 456); // "123..456" echo new IntervalCriterionValue(123, null); // "123.." echo new IntervalCriterionValue(null, 456); // "..456" echo new IntervalCriterionValue(123, 123); // "123" echo new IntervalCriterionValue(null, null); // ""
IntervalCriterionValue 实例可以在修改查询时由准则用来创建 BETWEEN ? AND ?
,>= ?
和 <= ?
条件。
集合值
集合值由 SetCriterionValue 实例表示。当指定为字符串时,使用 竖线 符号 "|" 来分隔值。可以使用以下任何语句创建集合值:
<?php use ICanBoogie\Facets\CriterionValue\SetCriterionValue; $value = SetCriterionValue::from('1|2'); // 1 or 2 $value = SetCriterionValue::from([ 1 => 'on', 2 => 'on' ]); // 1 or 2 $value = new SetCriterionValue([ 1, 2 ]); // 1 or 2
SetCriterionValue 实例也可以用作字符串。
<?php use ICanBoogie\Facets\CriterionValue\SetCriterionValue; echo new SetCriterionValue([ 1, 2, 3 ]); // "1|2|3" echo new SetCriterionValue([ 1 ]); // "1" echo new SetCriterionValue([ ]); // ""
SetCriterionValue 实例可以在修改查询时由准则用来创建 IN(?)
条件。
将准则与模型关联
准则是通过 activerecord
配置片段和 facets
键与模型关联的。模型的准则使用模型的标识符指定。从片段中合成了 activerecord_facets
配置。包通过将 criteria
和 criterion_list
获取器添加到 Model 类来实现,分别用来检索配置准则和与模型关联的 CriterionList 实例。
注意: 此功能目前需要 ICanBoogie 框架和 icanboogie/bind-facets 包。可以使用仅包含 icanboogie/prototype 包的类似功能实现。在这种情况下,您只需要为 Model 类定义 criteria
和 criterion_list
获取器。
以下示例演示了如何将 nid
和 slug
条件与 nodes
模型关联,以及如何将 month
和 year
条件与 articles
模型关联。
<?php // config/activerecord.php return [ 'facets' => [ 'nodes' => [ 'nid' => Icybee\Modules\Nodes\NidCriterion::class, 'slug' => Icybee\Modules\Nodes\SlugCriterion::class ], 'articles' => [ 'month' => Icybee\Modules\Articles\MonthCriterion::class, 'year' => Icybee\Modules\Articles\YearCriterion::class ] ] ];
请注意,条件是可以继承的。在我们的示例中,因为 articles
继承了 nodes
,所以它继承了其 nid
和 slug
条件。
获取与模型关联的条件
可以使用包添加的 criteria
获取器从模型中检索条件数组。获取器返回的条件和继承条件是在 activerecord_facets
配置中定义的。
<?php use ICanBoogie\ActiveRecord; $model = ActiveRecord\get_model('articles'); array_keys($model->criteria); # [ 'nid', 'slug', 'month', 'year' ]
criteria
和 criterion_list
获取器添加到了 Model 类中
获取与模型关联的 CriterionList 实例
可以使用包添加的 criterion_list
获取器从模型中检索与模型关联的 CriterionList 实例。获取器返回的是通过 criteria
获取器获取的条件创建的 CriterionList 实例。
<?php $criterion_list = $model->criterion_list;
要求
此包需要 PHP 5.5 或更高版本。
安装
composer require icanboogie/facets
文档
此包作为 ICanBoogie 框架的一部分进行了文档记录。文档。您可以使用 make doc
命令生成包及其依赖的文档。文档生成在 build/docs
目录中。需要 ApiGen。可以使用 make clean
命令清理该目录。
测试
运行 make test-container
以创建并登录到测试容器,然后运行 make test
以运行测试套件。或者,运行 make test-coverage
以带有测试覆盖率的运行测试套件。打开 build/coverage/index.html
以查看代码覆盖率的分解。
许可证
icanboogie/facets 在 新BSD许可证 下发布。