Elasticsearch 7.x を PHP で操作する方法

この記事では、PHPを使用してElasticsearch 7.xに接続し、データをインデックス化および検索する方法について説明します。
必要な環境は以下の通りです。
  • Laravel 8
  • PHP 7.3.4
  • MySQL 5.7
  • CentOS 8
Elasticsearchのクライアントをインストールします。

composer require elasticsearch/elasticsearch
インデックスを作成するためのパラメータ例です。

$settings = [
    'index' => '和歌データベース', // インデックス名(MySQLのデータベースに相当)
    'body' => [
        'settings' => [
            'number_of_shards' => 3, // シャード数
        ],
        'mappings' => [ 
            'properties' => [ // プロパティ設定(MySQLのカラムに相当)
                '作者' => [
                    'type' => 'text',
                    'store' => true,
                ],
                '本文' => [
                    'type' => 'text',
                ],
                'タイトル' => [
                    'type' => 'keyword',
                ]
            ]
        ]
    ]
];
テスト用データとして「chinese-poetry」リポジトリを使用します。 Chinese Poetry GitHub Repository
MySQLのテーブル作成スクリプト。

CREATE TABLE `詩人` (
    `id` bigint(20) NOT NULL AUTO_INCREMENT,
    `作者` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    `本文` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    `タイトル` text CHARACTER SET utf8 COLLATE utf8_unicode_ci,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=290 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
簡体字と繁体字の変換には次のツールを使用します。 HanziConvert GitHub Repository

// 簡体字から繁体字への変換
$str = "好難";
HanziConvert::convert($str, true);

// 繁体字から簡体字への変換
$str = "好難";
HanziConvert::convert($str);
JSONデータを読み込み、MySQLに挿入するスクリプト。

$dataContent = file_get_contents('./poet.song.0.json');
$parsedData = json_decode($dataContent, true);

if (!empty($parsedData)) {
    foreach ($parsedData as $item) {
        $PoetRecord = new Poet();
        $PoetRecord->author = HanziConvert::convert($item['author']);
        $PoetRecord->paragraphs = HanziConvert::convert(implode(',', $item['paragraphs']));
        $PoetRecord->title = HanziConvert::convert($item['title']);
        $PoetRecord->save();
    }
}
Elasticsearchクライアントの初期化とデータのインデックス化。

$clientBuilder = \Elasticsearch\ClientBuilder::create();
$clientBuilder->setHosts(['192.168.3.15:9200']);
$client = $clientBuilder->build();

$poets = Poet::all()->toArray();
foreach ($poets as $record) {
    $params = [
        'index' => '古文インデックス',
        'id' => '記録_' . $record['id'],
        'body' => [
            'id' => $record['id'],
            'author' => $record['author'],
            'paragraphs' => $record['paragraphs'],
            'title' => $record['title'],
        ],
    ];
    $response = $client->index($params);
}

$searchParams = [
    'index' => '古文インデックス',
    'body' => [
        'query' => [
            'match' => [
                'paragraphs' => '未離',
            ],
        ],
    ],
];

$results = $client->search($searchParams);
print_r($results);
検索結果の例。

Array
(
    [took] => 6
    [timed_out] => 
    [_shards] => Array
        (
            [total] => 1
            [successful] => 1
            [skipped] => 0
            [failed] => 0
        )

    [hits] => Array
        (
            [total] => Array
                (
                    [value] => 23
                    [relation] => eq
                )

            [max_score] => 9.34944
            [hits] => Array
                (
                    ...
                )
        )
)

タグ: Elasticsearch PHP laravel

7月22日 20:31 投稿