Laravel Eloquent如何搜索PostgreSQL JSONB字段的指定item值?
PostgreSQL jsonb数组对象属性匹配的正确Eloquent实现方式
你的PostgreSQL数据库中data字段为jsonb类型,存储的是包含多个对象的数组,当前通过ilike匹配整个字段实现搜索,但希望仅匹配数组内对象的item属性值,尝试->whereJsonContains('data->item', $searchInput)未得到预期结果,以下是正确实现方式:
示例数据
[ { "id": 1000, "item": "foo", "location": "test#1" }, { "id": 1001, "item": "bar", "location": "test#1" }, { "id": 1002, "item": "foo-bar", "location": "test#2" } ]
问题原因
whereJsonContains('data->item', $searchInput)写法错误,因为data->item会提取数组中所有对象的item值形成一个新数组(如["foo", "bar", "foo-bar"]),而whereJsonContains针对这种场景的精确匹配逻辑不成立;同时该方法仅支持精确匹配,无法实现你原本ilike的模糊搜索需求。
解决方案
1. 模糊匹配(替代原ilike逻辑,仅匹配item属性)
使用whereRaw结合PostgreSQL的jsonb_array_elements函数展开数组,对每个对象的item属性进行模糊匹配:
->whereRaw("EXISTS ( SELECT 1 FROM jsonb_array_elements(data) AS elem WHERE elem->>'item' ILIKE ? )", ['%' . $searchInput . '%'])
该语句会遍历data数组中的每个对象,只要有一个对象的item属性值模糊匹配$searchInput,就会返回这条记录。
2. 精确匹配item属性值
如果需要精确匹配item的某个值,正确的whereJsonContains写法是直接检查数组中是否存在包含指定item键值对的对象:
->whereJsonContains('data', ['item' => $searchInput])
内容的提问来源于stack exchange,提问作者Harold
相关产品推荐
相关产品推荐

