6

I've got this data in a JSONB field:

[
    'first_name' => 'Philipp',
    'last_name' => 'Kühn',
    'size' => 170,
    'hobbies' => [
      'daily' => 'beer',
    ],
    'skills' => [
      'drink beer',
      'drink more beer',
    ],
]

I'm pretty new to Laravel and Postgres so I wanted to do some basic queries.

Here are some queries that works fine: (json is the name of the column)

$users = User::whereRaw("json ->> 'first_name' = 'Philipp'")->get();

$users = User::whereRaw("json ->> 'size' > '160'")->get();

$users = User::whereRaw("json #>> '{hobbies, daily}' = 'beer'")->get();

Now I want to check if drink beer is in skills and the following code doesn't work:

$users = User::whereRaw("json -> 'skills' ? 'drink beer'")->get();

Here I got a syntax error:

SQLSTATE[42601]: Syntax error: 7 ERROR: syntax error at or near "$1"
LINE 1: select * from "users" where json ->> 'skills' $1 'drink beer...
^ (SQL: select * from "users" where json ->> 'skills' ? 'drink beer')

How can I search for drink beer?

3
  • 1
    Hu ho, it sounds PDO is taking the question mark as being a query parameter… Look at the documentation : positional parameters : php.net/manual/en/pdostatement.bindparam.php No idea how to get around this. Commented Aug 27, 2015 at 11:48
  • yes. this seems to be the problem. i've tested a raw query in postico and everything worked. argh... Commented Aug 27, 2015 at 11:57
  • 1
    what about stackoverflow.com/a/16312053/244058 ? Commented Aug 27, 2015 at 12:28

4 Answers 4

5

As suggested by @tapoueh on twitter, maybe a work around would be to use the operator's underlying function: jsonb_exists(jsonb, text). So your query would be

$users = User::whereRaw("jsonb_exists(json -> 'skills', 'drink beer')")->get();

Added by @docteur_klein : A link to a similar problem.

1
  • 1
    missing ) , check your query once again Commented Mar 3, 2017 at 5:33
3

With Laravel 5.6+ searching in a JSON becomes really easy

https://laravel.com/api/5.6/Illuminate/Database/Query/Builder.html#method_whereJsonContains

User::WhereJsonContains('json->skills', 'drink beer')->get();
1
1

If you need LIKE search, then use that:

\DB::table('users')
    ->whereRaw("json::json->>'skills' like '%drive a car%'")
    ->get();
0

If you need to search an value item inside array of objects, you can escape strings like this:

$query = "column @> '{\"INDEX_OF_ARRAY\":[{\"INDEX_OF_OBJECT\": \"".$searched_value."\"}]}'";
$colection = YourModel::whereRaw($query);
$colection->get();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.