Как сделать поиск laravel /asticsearch со связанными таблицами? - PullRequest
0 голосов
/ 14 ноября 2018

В моем приложении laravel 5.7 / mysql я использую эластичный поиск на основе статьи https://michaelstivala.com/learning-elasticsearch-with-laravel/.Мне понятно, как сохранять / удалять / искать данные, основанные на одной таблице.Но у меня есть таблицы:

CREATE TABLE `votes` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
    `description` MEDIUMTEXT NOT NULL COLLATE 'utf8mb4_unicode_ci',

с поиском по полям имени и описания

, но у меня также есть таблица

CREATE TABLE `vote_items` (
    `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
    `vote_id` INT(10) UNSIGNED NULL DEFAULT NULL,
    `name` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',

, и я хочу сделать поиск также наПоле имени.

Это кажется несколько хитрым.В моей модели голосования я определил методы для синхронизации данных сasticsearch:

<?php

namespace App;

use DB;

class Vote extends Model
{
    protected $table = 'votes';
    protected $elasticsearch_type  = 'vote';
    protected $primaryKey = 'id';
    ...
    public function getElasticsearchType(): string
    {
        return $this->elasticsearch_type;
    }

    protected static function boot() {
        parent::boot();

        static::saved(function ($vote) {
            $elastic = app(\App\Elastic\Elastic::class);
            $elasticsearch_root_index  = config('app.elasticsearch_root_index');
            $elasticsearch_type        = with(new Vote)->getElasticsearchType();

            $elastic->delete([
                'index' => $elasticsearch_root_index,
                'type'  => $elasticsearch_type,
                'id'    => $vote->id,
            ]);

            if ($vote->status == 'A') { // only active votes must be saved in elasticsearch
                $elastic->index([
                    'index' => $elasticsearch_root_index,
                    'type'  => $elasticsearch_type,
                    'id'    => $vote->id,
                    'body'  => [
                        'id'          => $vote->id,
                        'slug'        => $vote->slug,
                        'name'        => $vote->name,
                        'description' => $vote->description,
                    ]
                ]);
            } // if ($vote->status == 'A') { // only active votes must be saved in elasticsearch

        });
        static::deleted(function ($vote ) {
            $elastic = app(\App\Elastic\Elastic::class);
            $elasticsearch_root_index  = config('app.elasticsearch_root_index');
            $elasticsearch_type        = with(new Vote)->getElasticsearchType();
            $elastic->delete([
                'index' => $elasticsearch_root_index,
                'type' => $elasticsearch_type,
                'id' => $vote->id,
            ]);
        });
    }


    public static function bulkVotesToElastic()
    {
        $elastic = app(\App\Elastic\Elastic::class);

        $elasticsearch_root_index  = config('app.elasticsearch_root_index');
        $elasticsearch_type        = with(new Vote)->getElasticsearchType();

        Vote::chunk(100, function ($Votes) use ($elastic, $elasticsearch_root_index, $elasticsearch_type) {
            foreach ($Votes as $nextVote) {
                if ($nextVote->status!= 'A') continue; // only active votes must be saved in elasticsearch
                $elastic->index([
                    'index' => $elasticsearch_root_index,
                    'type'  => $elasticsearch_type,
                    'id'    => $nextVote->id,
                    'body'  => [
                        'id'          => $nextVote->id,
                        'slug'        => $nextVote->slug,
                        'name'        => $nextVote->name,
                        'description' => $nextVote->description,
                    ]
                ]);
            }
        });
    }


}

Полагаю, я мог бы создать аналогичные методы для модели voice_items и сохранить все данные с другим типом, но я считаю, что это недопустимый способ... Какой способ действителен?Есть ли примеры, как это можно реализовать?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...