Laravel雄辩,搜索列的文本像一个数组的内容(但不是在模型中强制转换)



有一个模型(product_stocks),它有一个名为variant_avi的列,包含像[21,3]这样的文本,我想检查它是否包含像[2,3,14,21]这样的数组中的任何元素。

部分product_stocks表迁移:

$table->text('variant_avi');

我知道最简单的方法,就是将列转换为数组,但是我不能改变模型。

有办法吗?

一种可能使用多个LIKE运算符来检查variant_avi列是否包含数组中的任何值:

$values = [2, 3, 14, 21];
$results = ProductStock::where(function($query) use ($values) {
foreach ($values as $value) {
$query->orWhere('variant_avi', 'like', "%{$value}%");
}
})
->get();

请记住,使用LIKE操作符可能不如将列转换为数组那么有效。如果可能的话,最好更改模型并将variant_avi列强制转换为数组,以便您可以使用更有效的数组比较操作符。

如果你不能改变这个模型,但上面的解决方案会产生性能问题,我建议建立另一个表作为物化视图。

构建一个物化视图来存储variant_avi列作为JSON将是一个很好的解决方案,因为它将允许您使用更有效的数组比较操作符而不改变原始模型。

如果你正在使用Postgres,这是一个本地特性:

DB::statement('CREATE MATERIALIZED VIEW product_stocks_json AS
SELECT id, variant_avi::JSON AS variant_avi
FROM product_stocks
');

在MySQL中需要一点额外的工作:https://fromdual.com/mysql-materialized-views

你也可以利用模型事件在Laravel保持一个单独的表更新:https://laravel.com/docs/9.x/eloquent#events