как реализовать Elasti c Поиск в Laravel для автозаполнения - PullRequest
1 голос
/ 17 марта 2020

Я следовал этому замечательному учебнику Сделано с любовью ES laravel Учебник , чтобы реализовать ES в моем Laravel приложении для электронной коммерции, которое я создаю. Я заставил это работать, но я хотел немного подправить его, потому что на данный момент результаты работают только тогда, когда мой термин запроса соответствует точно целому слову, которое у меня есть в одном из моих продуктов.

У меня есть здоровье Nut Bar называется Bear Naked Bar Миндаль, но когда я набираю «bea», он ничего не соответствует, но когда я набираю «Bear», он работает.

Это мой поисковый запрос на данный момент.

$model = new ProductsListing;

$items = $this->elasticsearch->search([
    'index' => $model->getSearchIndex(),
    'type' => $model->getSearchType(),
    'body' => [
        'query' => [
            'multi_match' => [
                'fields' => ['brand', 'name^5', 'description'],
                'query' => $query,
            ],
        ],
    ],
]);

Мне нужна помощь, чтобы настроить запрос так, чтобы я получал результаты по мере ввода.

Ответы [ 3 ]

2 голосов
/ 17 марта 2020

Я не знаком с PHP and laravel, но причина, по которой он не дает результата на bea b / c, вы используете запрос на совпадение, который применяет тот же анализатор, который используется во время индекса, и Ваш текст bear naked almond bar создает токены bear, naked, almond и bar, а bea не соответствует ни одному токену.

Вы можете изменить свой запрос ниже (не уверен в правильном синтаксисе префикса в laravel).

$model = new ProductsListing;

$items = $this->elasticsearch->search([
    'index' => $model->getSearchIndex(),
    'type' => $model->getSearchType(),
    'body' => [
        'query' => [
            'prefix' => [. --> changed to prefix query.
                'fields' => ['brand', 'name^5', 'description'],
                'query' => $query,
            ],
        ],
    ],
]);

Я предполагаю, что вы используете поле text с анализатором standard по умолчанию и analysis API, вы можете проверить токены, сгенерированные для вашего текста.

POST your-index / _analyze

{
    "text": "bear naked almond bar",
    "analyzer" : "standard"
}

{
    "tokens": [
        {
            "token": "bear",
            "start_offset": 0,
            "end_offset": 4,
            "type": "<ALPHANUM>",
            "position": 0
        },
        {
            "token": "naked",
            "start_offset": 5,
            "end_offset": 10,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "almond",
            "start_offset": 11,
            "end_offset": 17,
            "type": "<ALPHANUM>",
            "position": 2
        },
        {
            "token": "bar",
            "start_offset": 18,
            "end_offset": 21,
            "type": "<ALPHANUM>",
            "position": 3
        }
    ]
}

Дополнительная информация о запросе на совпадение, запросе префикса и различных способах реализации Автозаполнение можно найти в этом блоге.

0 голосов
/ 18 марта 2020

Мне удалось получить помощь здесь: github

, и это было идеальное решение. Спасибо Энрико Зимуэль.

0 голосов
/ 17 марта 2020

Попробуйте match_phrase_prefix с must query inside bool запросом вместо multi_match ... вы начнете получать результат при вводе ...

например

$query = '{
          "size": 10, //size of return array 
          "query": {
            "bool": {
              "must": [
                {
                  "match_phrase_prefix": {
                    "tag":"' . $filter_name . '"
                    }
                }
              ],
            }
          }
        }';

//Now pass this $query variable to your ES request

есть два метода: 1- prefix, 2- match_phrase_prefix

Пожалуйста, смотрите документацию для префикса и match_phrase_prefix

...