I have a table ‘sometable’ with a JSON field named ‘jsonval’, which contains a JSON object with the property ‘programs’ that contains an array of objects with the property ‘id’
I want to search for records that contain jsonval.programs.id = 14
The following query works:
SELECT id, jsonval, JSON_EXTRACT(jsonval, '$.programs[*].id') FROM `sometable`
WHERE JSON_EXTRACT(jsonval, '$.programs[*].id') LIKE '%"14"%';
because JSON_EXTRACT(jsonval, '$.programs[*].id')
results in the string representation of the array holding the id’s, i.e.: ["14","26"]
But there should be a more elegant solution, maybe using JSON_CONTAINS?
2
Answers
I think Using
JSON_CONTAINS
can make your query more explicit and potentially faster by avoiding string-based operations like LIKE.This is the current solution. MySQL 8.0.17 or later support the
MEMBER OF
predicate.This is better than using JSON_CONTAINS() because you can create a multi-valued index on the array (also requires MySQL 8.0.17).
The EXPLAIN shows that it uses the index:
In general I think anytime you need to reference a JSON column in your WHERE clause, you’re better off storing data in normal rows and columns. Writing queries for JSON data results in more complex queries and some cases cannot be optimized.