Возможность преобразования данных в формат JSON и из него появилась в Laravel в версии 5.0, но раньше это было сделано только для удобства, а данные хранились по-прежнему в текстовом поле. Но в MySQL 5.7 появился настоящий тип JSON.
В Laravel 5.3 появился простой синтаксис для поиска и изменения данных на основе значений конкретных ключей в JSON-столбцах.
Предположим, у нас есть таблица с JSON-столбцом:
...
class CreateContactsTable extends Migration
{
public function up()
{
Schema::create('contacts', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->json('meta');
$table->timestamps();
});
}
Представим, что у каждого контакта есть обязательные данные, например, его имя, а набор остальных свойств у разных контактов может различаться. Возможно лучше всего хранить их в JSON-столбце, в примере это столбец meta.
Предположим, один из контактов выглядит так (вывод в JSON для читаемости):
{
"id": 1,
"name": "Alphonse",
"meta": {
"wants_newsletter": true,
"favorite_color": "red"
}
}
Итак, давайте найдём всех наших пользователей, чей любимый цвет красный. Посмотрите на пример ниже: сначала мы указываем столбец (meta), затем ставим стрелку (->), и указываем название ключа JSON-свойства (favorite_color).
$redLovers = DB::table('users')
->where('meta->favorite_color', 'red')
->get();
Это означает «найди каждую запись таблицы users, у которой в meta хранится JSON-объект, у которого есть ключ favorite_color, который равен red».
А если нам надо указать, что Alphonse больше не хочет получать рассылку новостей?
DB::table('users')
->where('id', 1)
->update(['meta->wants_newsletter' => false]);
Это здорово, потому что, даже если раньше ключа wants_newsletter в этой записи не было, теперь он в ней будет, и ему будет присвоено значение false.
Чувствуете мощь? Мы можем запрашивать данные на основе свойств в JSON-столбцах и мы можем изменять отдельные части в JSON-столбце, не проверяя и не переживая за остальные его части. Великолепно.
В MariaDB нет JSON-столбцов, и в PostgreSQL нет JSON-столбцов, и с ними данная функция не будет работать корректно. Поэтому считайте, что пока эта функция только для MySQL 5.7+.
Комментарии (2)
Хорошая тема, как раз подходящие данные для этого имеются. А то по столбцу на каждое...
1. Как задать такие поля через Eloquent?
2. Можно ли в запросах использовать данные из массивов? Например, есть
и либо добавить адрес, либо сделать запрос по записям, у которых в этом массиве есть Москва, например.