You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Laravel Eloquent实现PostgreSQL不区分大小写的whereIn查询

解决方案:Laravel Eloquent实现PostgreSQL不区分大小写的whereIn查询

针对你遇到的问题——用Laravel Eloquent的whereIn无法实现不区分大小写的标签名称匹配,结合PostgreSQL的特性,这里有几个靠谱的解决办法:

方法1:使用PostgreSQL的ILIKE ANY语法

PostgreSQL原生支持ILIKE进行不区分大小写的匹配,搭配ANY可以直接匹配数组中的元素,非常适合你的场景:

$tags = Category::whereRaw('name ILIKE ANY (?)', [$tag_names])
    ->pluck('id')
    ->toArray();

这个写法会生成类似SELECT id FROM categories WHERE name ILIKE ANY (ARRAY['Tag1', 'tag2', 'TAG3'])的SQL,自动忽略大小写匹配数组中的所有名称。

方法2:统一转换为小写后用whereIn

另一种思路是把数据库中的name字段和查询数组都转换为小写,再用普通的whereIn匹配:

// 先把查询数组转成小写
$lowerTagNames = array_map('strtolower', $tag_names);

// 用DB::raw转换数据库字段为小写
$tags = Category::whereIn(DB::raw('LOWER(name)'), $lowerTagNames)
    ->pluck('id')
    ->toArray();

如果你的categories表数据量比较大,建议给LOWER(name)创建一个函数索引来提升查询性能:

CREATE INDEX idx_categories_name_lower ON categories (LOWER(name));

这个方案的优势是查询性能更稳定,尤其是在有索引加持的情况下。

方法3:循环添加orWhere(适合小批量数据)

如果你的$tag_names数组元素不多,也可以通过循环添加不区分大小写的orWhere条件:

$query = Category::query();
foreach ($tag_names as $name) {
    $query->orWhere('name', 'ILIKE', $name);
}

$tags = $query->pluck('id')->toArray();

不过要注意,当数组元素较多时,这种方式会生成很长的SQL语句,性能不如前两种方法,只推荐小数据量场景使用。

内容的提问来源于stack exchange,提问作者Daniel Marques

火山引擎 最新活动