有一个模型(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