【Laravel】JSONファイルをデータベースに取り込むには?日本語の場合は注意点あり!

laravel Laravel

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ならかんたんです。便利!

コメント

タイトルとURLをコピーしました