使用Laravel的eloquent在JSON专栏中搜索

时间:2017-06-21 07:37:12

标签: php mysql laravel laravel-5 eloquent

我一直在与Laravel 5.4一起工作,并且我遇到了一个问题。

我有一个名为帖子的数据库表,其中有一个名为template_ids的列。它以json_encoded格式存储值,如:

["1","25","48"]

现在,我想根据ID数组对我的查询应用过滤器:

$id_access = array:3 [ 
  0 => "1"
  1 => "3"
  2 => "48"
]

我要做的是搜索数据库列$id_access中是否存在任何template_ids值。

我试过了:

Post::where('accessable_to',1)->whereIn('template_ids', $template_access_array)->paginate(3);

另外,我试过了:

Post::where('accessable_to',1)->whereRaw("JSON_CONTAINS(template_ids, ".$template_access.")")->paginate(3);

已经查看this,但它不适合我。

2 个答案:

答案 0 :(得分:4)

要查看template_ids JSON字段是否包含针数组中的“任何”值,您需要使用需要MySQL 5.7的多个OR'd JSON_CONTAINS条件:

$ids = ['1', '3', '48'];

Post::where('accessable_to', 1)
    ->where(function ($query) use ($ids) {
        $firstId = array_shift($ids);

        $query->whereRaw(
            'JSON_CONTAINS(template_ids, \'["' . $firstId . '"]\')'
        );

        foreach ($ids as $id) {
            $query->orWhereRaw(
                'JSON_CONTAINS(template_ids, \'["' . $id . '"]\')'
            );
        }

        return $query;
    });

return Post::paginate(3);

Laravel的查询构建器将生成如下查询:

SELECT * FROM "posts" 
WHERE "accessable_to" = ? AND (
    JSON_CONTAINS(template_ids, '["1"]') OR 
    JSON_CONTAINS(template_ids, '["3"]') OR 
    JSON_CONTAINS(template_ids, '["48"]')
)

其目标是在template_ids JSON类型字段中具有任何这些ID的记录。

您可能有兴趣阅读相关的Laravel internals proposal

答案 1 :(得分:0)

怎么说:

$query = Post::where([]);

$query->where(function($query, $template_ids){
  foreach ($template_ids as $id){
     $query->orWhere('searching_field', 'like', '%'.$id.'%');
  } 
});

$query->get()