目录

Meta查询

Metable特征提供了许多查询范围,以便于根据模型附带的元修改查询。

检查是否存在键值

要仅返回具有分配给特定键的值的记录,可以使用whereHasMeta()。 您还可以将数组传递给此方法,这将导致查询返回附加到一个或多个提供的键的任何模型。

<?php
$models = MyModel::whereHasMeta('notes')->get();
$models = MyModel::whereHasMeta(['queued_at', 'sent_at'])->get();

如果您希望将查询限制为仅返回包含所有提供的键的meta的模型,则可以使用whereHasMetaKeys()。

<?php
$models = MyModel::whereHasMetaKeys(['step1', 'step2', 'step3'])->get();

您还可以使用whereDoesntHaveMeta()查询不包含元键的记录。 它的签名与whereHasMeta()的签名相同。

<?php
$models = MyModel::whereDoesntHaveMeta('notes')->get();
$models = MyModel::whereDoesntHaveMeta(['queued_at', 'sent_at'])->get();

比较键值

您可以根据存储在元键中的值来限制查询。 whereMeta()方法可用于使用Royalcms查询构建器的where()方法接受的任何运算符来比较值。

<?php
// omit the operator (defaults to '=')
$models = MyModel::whereMeta('letters', ['a', 'b', 'c'])->get();

// greater than
$models = MyModel::whereMeta('name', '>', 'M')->get();

// like
$models = MyModel::whereMeta('summary', 'like', '%bacon%')->get();

//etc.

whereMetaIn()方法也可用于查找值与预定义选项集之一匹配的记录。

<?php
$models = MyModel::whereMetaIn('country', ['CAN', 'USA', 'MEX']);

whereMeta()和whereMetaIn()方法执行字符串比较(词典排序)。 传递给这些方法的任何非字符串值都将序列化为字符串。 这对于评估等式(=)或不等式(<>)很有用,但对于非字符串数据类型可能与其他一些运算符不可预测。

<?php
// array value will be serialized before it is passed to the database
$model->setMeta('letters', ['a', 'b', 'c']);

// array argument will be serialized using the same mechanism
// the original model will be found.
$model = MyModel::whereMeta('letters', ['a', 'b', 'c'])->first();

根据原始数据的格式,可以使用SQL like运算符和字符串参数来比较数据的子集。

<?php
$model->setMeta('letters', ['a', 'b', 'c']);

// check for the presence of one value within the json encoded array
// the original model will be found
$model = MyModel::whereMeta('letters', 'like', '%"b"%' )->first();

将整数或浮点值与<,<=,> =或>运算符进行比较时,请使用whereMetaNumeric()方法。 这将在执行比较之前将值转换为数字,以避免词典排序的常见缺陷(例如,’11’大于’100’)。

<?php
$models = MyModel::whereMetaNumeric('counter', '>', 42)->get();

结果排序

您可以将order by子句应用于查询,以按元键的值对结果进行排序。

<?php
// order by string value
$models = MyModel::orderByMeta('nickname', 'asc')->get();

//order by numeric value
$models = MyModel::orderByMetaNumeric('score', 'desc')->get();

默认情况下,将对与查询的其余部分匹配的所有记录进行排序。 没有分配给要排序的键的元数据的任何记录将被视为具有null值。

要自动排除未分配给排序键的所有记录,请将true作为第三个参数传递。 这将在排序时执行内部联接而不是左联接。

<?php
// sort by score, excluding models which have no score
$model = MyModel::orderByMetaNumeric('score', 'desc', true)->get();

//equivalent to, but more efficient than
$models = MyModel::whereHasMeta('score')
    ->orderByMetaNumeric('score', 'desc')->get();

关于优化的记录

Royalcms-Metable是处理许多不同形状和大小数据的便捷方式。 它被设计用于处理只有表中所有模型的子集才有需要的数据。

例如,您有一个带有模板字段的页面模型,每个模板都需要一些额外的字段来修改它的显示方式。 如果你有X模板,每个模板最多有Y个字段,那么将所有这些作为列添加到页面表将很快失控。 相反,将这些模板字段作为元素附加到Page模型可以使处理此用例变得微不足道。

Royalcms-Metable可以很容易地将任何数据附加到您的模型中。 但是,对于足够大的数据集或经常查询的数据,使用常规数据库列通常会更有效,以便利用本机SQL数据类型和索引。 最佳解决方案取决于您的使用案例。