Search in Json column with Laravel
Stefan Izdrail
Founder & Senior Architect · 2026-06-29
Title: Efficient Searching of JSON Data in Laravel using Eloquent Models
Body:
In this comprehensive blog post, we will explore effective ways to search through JSON data stored within columns in a Laravel application using Eloquent models. We'll begin by understanding the problem and then move onto discussing the available solutions. To start with, let's look at the following example where our email table has a column named 'To,' which holds an array of email addresses:
[
{
"emailAddress": {
"name": "Test",
"address": "test@example.com"
}
},
{
"emailAddress": {
"name": "Test 2",
"address": "test2@example.com"
}
}
]
We wish to find all emails sent to 'test@example.com'. Using Laravel's whereJsonContains() method as shown in the introductory code snippet, we might assume that the query should return our desired result:
DB::table('emails')->whereJsonContains('to->emailAddress->address', 'test@example.com')->get();
However, this turns out to be an inaccurate approach. The query is actually translated to:
select * from `emails` where json_contains(`to`->'$."emailAddress"."address"', '\"test@example.com\"')
This translation results in the lack of a match for our search term. So, how can we efficiently solve this issue? Let's discuss several possible solutions to address this problem and find all emails sent to 'test@example.com'.
Solution 1: Accessing JSON Data Directly via Database Connections
A straightforward alternative would be accessing the database connection directly using DB::connection()->rawQuery() or DB::select(). This approach involves constructing SQL queries that perform specific searches on the JSON data stored in the database. For instance, to search for 'test@example.com' emails, you can write:
DB::table('emails')->selectRaw('JSON_EXTRACT(to, '$."emailAddress"."address") as email')->whereRaw('JSON_SEARCH(`to`->'$."emailAddress"."address"', 'all', "\"test@example.com\"'", null, 'any') IS NOT NULL')->get();
Solution 2: Using Eloquent Relations
Another solution is to break down your JSON data into multiple models using Eloquent relations and searching through individual models. For instance, you can create a new model called EmailAddresses that has one-to-many relationship with Emails and add the following code snippet:
EmailAddress::where('address', 'test@example.com')->with('emails')->get();
In case you need to search multiple email addresses in a single query, you could use the orWhere method on the where() method of your model:
EmailAddress::where('address', 'test@example.com')->orWhere('address', 'test2@example.com')->with('emails')->get();
Solution 3: Using External Libraries for Better JSON Queries
If you have a large number of emails to search through and performance is crucial, consider using external libraries like PhpQuery or DoctrineExtensions (PHP Data Objects) that provide better JSON querying capabilities than Eloquent models. For instance:
$query = DB::connection()->getDoctrineConnection();
$dql = "SELECT e FROM Emails AS e WHERE JSON_SEARCH(e.to, 'all', '\"test@example.com\"'", null, 'any') IS NOT NULL";
$result = $query->executeQuery($dql);
Conclusion:
With these different approaches available, you can select the one that best suits your needs and application requirements. Remember to ensure proper performance and maintainability when selecting a solution for searching through JSON data in Laravel applications using Eloquent models. Always keep in mind that backups are essential for maintaining data integrity when making significant changes to your database structure or storage. Happy coding!