JSONファイルをデータベースに取り込む方法を紹介します。
大量にあるJSONファイルを一気にデータベースに取り込んで、かんたんに参照したり、検索できるようにしたいケースを想定しています。
JSONカラムを作成する
LaravelはMySQLのJSON型をサポートしています。マイグレーションを作成し実行することで、JSONカラムをいともかんたんに作成できます。
まずはartisanコマンドでマイグレーションファイル・コントローラー・モデルを一気に作成します。
php artisan make:model -mr Sample
マイグレーションファイルを作成。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Query\Expression;
class CreateSampleTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('samples', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('name')->comment("ファイル名")->nullable();
$table->json('json')->comment("JSONファイル")->nullable();
}
}
ここでは、ファイル名と内容を格納するカラムをつくってみました。
JSONファイルのインポート
作成したJSONカラムにJSONファイルをインポートします。
storage/appディレクトリにjsonディレクトリを作成し、中にJSONファイルを保存しておいてください。jsonファイルを読み込んで、データベースにインポートします。
※ただし日本語を含むデータの場合は次の見出しを参照してください!このままやると検索性に支障が出ます。
use App\Sample;
/**
* importJsonToDB
*
* @return void
*/
public function importJsonToDB()
{
// ファイルリストを取得する
$files=glob(storage_path("app/json")."/*.json");
// ファイルを取り込む
foreach($files as $file){
// ファイル内容を取得して、JSONオブジェクトに変換する
$jsonObject=json_decode(file_get_contents($file),true);
// データベースに追加する
$s=new Sample();
$s->name=basename($file);
$s->json=$jsonObject;
$s->save();
}
}
ざっとこんなものでしょうか。
日本語を含む場合はUnicodeエンコードしないようにすること!
JSONカラムは内部的にはLongTextで実装されています。取得される文字列がUnicodeエンコードされていると、検索することができないという問題があります。そこで、日本語を含むJSON(UnicodeエンコードされているJSON)については、以下のように取り込む必要があります。
$sample = DB::table("samples");
$insertdata = [
"json" => json_encode(json_decode(file_get_contents($file)), JSON_UNESCAPED_UNICODE),
];
$question->insert($data);
これならそのままの文字列で登録されるため、検索できます。
データベースからJSONを参照する
やってみるとわかりますが、この状態で取得してみるとただのテキストとして返ってきます。
Sample::find(1)->json;
→テキストとして返って来てしまう
これはモデルでキャストを設定していないからです。
キャストを設定すると、連想配列として返ってくるようになります。
Sampleモデルを以下のようにします。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Sample extends Model
{
protected $casts = [
"json"=>"json", //カラム名=>タイプ
];
}
JSON型のカラムをjsonとして扱うように設定しておくと、連想配列として取得することができるようになります。これを忘れると、せっかくのJSONカラムもテキストと変わらない挙動となってしまいます。忘れずに設定しましょう!
まとめ
ここまでやって再度取得してみると、きちんと連想配列としてJSONが取得できるようになっています。
JSONのバルクインポートもLaravelならかんたんです。便利!
コメント