Elasticsearch и Laravel scout-elasticsearch-driver возвращают пустой ответ

Сначала я использую scout-elasticsearch-driver для Laravel Scout: https://github.com/babenkoivan/scout-elasticsearch-driver

Я шаг за шагом следил за файлом readme, создавал индекс, переносил индекс, настраивал сопоставление и User::search()->get() возвращает пустой массив.

Очевидно, моя база данных перенесена и заполнена.

Я хочу найти пользователя по:

  • Его first_name
  • Его last_name
  • Его псевдоним

Итак, я создал IndexConfigurator:

class UserIndexConfigurator extends IndexConfigurator
{
   use Migratable;

   /**
   * @var array
   */
   protected $settings = [
     //
   ];
}

Создано SearchRule:

class UserSearchRule extends SearchRule
{
   public function buildQueryPayload()
   {
       $query = $this->builder->query;

       return [
          'should' => [
              [
                'match' => [
                   'first_name' => [
                              'query' => $query
                          ]
                      ]
                  ],
                  [
                      'match' => [
                          'last_name' => [
                              'query' => $query
                          ]
                      ]
                  ],
                  [
                      'match' => [
                          'nick_name' => [
                              'query' => $query
                          ]
                      ]
                  ]
              ]
          ];
   }
}

Сконфигурировал мою модель пользователя соответственно:

<?php
class User extends Authenticatable

  {
    useSearchable;
    /**
     * @var string
     */
    protected $indexConfigurator = UserIndexConfigurator::class;

    /**
     * @var array
     */
    protected $searchRules = [UserSearchRule::class ];

    /**
     * @var array
     */
    protected $mapping = ['properties' => ['first_name' => ['type' => 'text'], 'last_name' => ['type' => 'text'], 'nick_name' => ['type' => 'text'], ]];
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['id', 'first_name', 'last_name', 'nick_name', ];
  }

Я что-то пропустил?

РЕДАКТИРОВАТЬ 1: Результат запроса curl к кластеру elasticsearch

curl -XGET "http://localhost:9200/user/_search?pretty=true&q=*:*"

curl -XGET на http: // localhost: 9200

ИЗМЕНИТЬ 2:

curl -XGET "http://localhost:9200/user?pretty=true"

фактическое отображение пользовательского индекса

Печать запроса, созданного:

dd(User::search('lo')->explain());

объясните эластичный поисковый запрос

ИЗМЕНИТЬ 3 Конфигурация драйвера Laravel scout и elasticsearch:

scout_elastic.php

<?php declare(strict_types = 1);

return [
    'client' => [
        'hosts' => [
            env('SCOUT_ELASTIC_HOST', 'localhost:9200'),
        ],
    ],
    'update_mapping' => env('SCOUT_ELASTIC_UPDATE_MAPPING', true),
    'indexer' => env('SCOUT_ELASTIC_INDEXER', 'single'),
    'document_refresh' => env('SCOUT_ELASTIC_DOCUMENT_REFRESH', 'wait_for'),
];

scout.php

<?php declare(strict_types = 1);

return [

    /*
    |--------------------------------------------------------------------------
    | Default Search Engine
    |--------------------------------------------------------------------------
    |
    | This option controls the default search connection that gets used while
    | using Laravel Scout. This connection is used when syncing all models
    | to the search service. You should adjust this based on your needs.
    |
    | Supported: "algolia", "null", "elastic"
    |
    */

    'driver' => env('SCOUT_DRIVER', 'elastic'),

    /*
    |--------------------------------------------------------------------------
    | Index Prefix
    |--------------------------------------------------------------------------
    |
    | Here you may specify a prefix that will be applied to all search index
    | names used by Scout. This prefix may be useful if you have multiple
    | "tenants" or applications sharing the same search infrastructure.
    |
    */

    'prefix' => env('SCOUT_PREFIX', ''),

    /*
    |--------------------------------------------------------------------------
    | Queue Data Syncing
    |--------------------------------------------------------------------------
    |
    | This option allows you to control if the operations that sync your data
    | with your search engines are queued. When this is set to "true" then
    | all automatic data syncing will get queued for better performance.
    |
    */

    'queue' => env('SCOUT_QUEUE', true),

    /*
    |--------------------------------------------------------------------------
    | Chunk Sizes
    |--------------------------------------------------------------------------
    |
    | These options allow you to control the maximum chunk size when you are
    | mass importing data into the search engine. This allows you to fine
    | tune each of these chunk sizes based on the power of the servers.
    |
    */

    'chunk' => [
        'searchable' => 500,
        'unsearchable' => 500,
    ],

    /*
    |--------------------------------------------------------------------------
    | Soft Deletes
    |--------------------------------------------------------------------------
    |
    | This option allows to control whether to keep soft deleted records in
    | the search indexes. Maintaining soft deleted records can be useful
    | if your application still needs to search for the records later.
    |
    */

    'soft_delete' => false,

    /*
    |--------------------------------------------------------------------------
    | Algolia Configuration
    |--------------------------------------------------------------------------
    |
    | Here you may configure your Algolia settings. Algolia is a cloud hosted
    | search engine which works great with Scout out of the box. Just plug
    | in your application ID and admin API key to get started searching.
    |
    */

    'algolia' => [
        'id' => env('ALGOLIA_APP_ID', ''),
        'secret' => env('ALGOLIA_SECRET', ''),
    ],

];

РЕДАКТИРОВАТЬ 4. Обновлено сопоставление elasticsearch

php artisan elastic:update-mapping App\\Models\\User

Дает:

{
  "user" : {
    "aliases" : {
      "user_write" : { }
    },
    "mappings" : {
      "users" : {
        "properties" : {
          "first_name" : {
            "type" : "text",
            "analyzer" : "standard"
          },
          "id" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          },
          "last_name" : {
            "type" : "text",
            "analyzer" : "standard"
          },
          "nick_name" : {
            "type" : "text",
            "analyzer" : "standard"
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "creation_date" : "1552675390883",
        "number_of_shards" : "5",
        "number_of_replicas" : "1",
        "uuid" : "hdtsA8ncQNC8rrI5Tr853A",
        "version" : {
          "created" : "6050499"
        },
        "provided_name" : "user"
      }
    }
  }
}

person loic.lopez    schedule 26.11.2018    source источник
comment
Вам необходимо предоставить отображение для вашего индекса.   -  person Archit Saxena    schedule 12.03.2019
comment
@ArchitSaxena, спасибо за ответ, но protected $mapping в моей User модели это не отображение моего индекса?   -  person loic.lopez    schedule 12.03.2019
comment
Ой, извините, я, должно быть, блеснул. Мне это нравится. Можете ли вы распечатать эластичный DSL-запрос, который генерируется вашим кодом. Ваше сопоставление в коде выглядит хорошо, но чтобы убедиться, что фактический индекс, который вы запрашиваете, имеет такое же сопоставление, можете ли вы опубликовать ответ curl -XGET host:9200/user_index?   -  person Archit Saxena    schedule 13.03.2019
comment
@ArchitSaxena спасибо за ответ, все в порядке, см. Мою правку :)   -  person loic.lopez    schedule 13.03.2019
comment
Эй, это мне мало что говорит. Попробуйте curl -XGET host:9200/user Это должно дать вам фактическое отображение индекса. То, что вы добавили, является результатом поиска. Кроме того, вы можете распечатать запрос, который дает User::search()->get()?   -  person Archit Saxena    schedule 14.03.2019
comment
@ArchitSaxena еще раз спасибо за помощь, засеять мое второе редактирование   -  person loic.lopez    schedule 14.03.2019
comment
Я думаю, есть проблема с тем, как вы настроили скаут. Просматривая документацию, кажется, что scout по умолчанию поставляется с драйвером Algolia. Я предполагаю, что вы добавили драйвер для elasticsearch? Напечатанный вами запрос не похож на DSL-запрос elasticsearch (актуальна только часть hits._payload.body). Кроме того, я не понимаю, почему curl -XGET "http://localhost:9200/user?pretty=true" вернул mappings: {}. Все это указывает на то, что есть некоторая проблема с настройкой scout, потому что он не может взаимодействовать с elasticsearch.   -  person Archit Saxena    schedule 15.03.2019
comment
Вам нужно будет опубликовать, какой движок и его конфигурацию (если есть), которую вы добавили, специфичны для elasticsearch. Раньше я не использовал scout или Laravel, но могу взглянуть.   -  person Archit Saxena    schedule 15.03.2019
comment
Я обновил свой пост с помощью файлов конфигурации.   -  person loic.lopez    schedule 15.03.2019
comment
@ArchitSaxena запустив php artisan elastic:update-mapping App\\Models\\User отображение было обновлено, см. Мое четвертое обновление.   -  person loic.lopez    schedule 15.03.2019


Ответы (2)


Решением было обновить UserSearchRule:

<?php declare(strict_types = 1);

namespace App\Models\SearchRules;

use ScoutElastic\SearchRule;

/**
 * Class UserSearchRule
 *
 * @package App\Models\SearchRules
 */
class UserSearchRule extends SearchRule
{

    /**
     * @inheritdoc
     */
    public function buildQueryPayload()
    {
        $query = $this->builder->query;

        return [
            'must'  => [
                'multi_match'   => [
                    'query'     => $query,
                    'fields'    => ['first_name', 'last_name', 'nick_name'],
                    'type'      => 'phrase_prefix',
                ],
            ],
        ];
    }
}
person loic.lopez    schedule 11.04.2019

Я попробовал ответить, но со своей стороны не работает.

Если ответ не сработает, мы можем сделать это вручную и получить результаты обращений.

   $query = request()->has('q') ? request('q') : '*';
   $results = Product::search($query)->raw()['hits'];
   $products = collect($results['hits'])->pluck('_source');
person superern    schedule 01.07.2019