Laravel Scout/Meilisearch - фильтр по столбцу, недоступному для поиска
Я хочу сделать так, чтобы я мог фильтровать результаты на основе столбца, который не доступен для поиска с помощью Meilisearch и Laravel scout.
Итак, представьте себе таблицу «Комментарии» со следующими столбцами, доступными для поиска:
public function toSearchableArray() {
$array = Arr::only(
$this->toArray(),
['id','title', 'link', 'raw_text', 'subchan', 'nsfw']
);
return $array;
}
Но получать результаты только после определенной даты:
Comment::search($query, ['filters' => 'created_at > 795484800'])
Для этого мне нужно добавить toSearchableArray разведчика. Проблема в том, что когда пользователь выполняет поиск, результаты
created_at
также будет запрошен.
3 ответа
Если я правильно вас понял, вы хотите иметь возможность фильтровать по столбцу, но он не должен быть доступен для поиска, т.е. ввод «795» в качестве запроса не должен возвращать все результаты, где «795» является частью временной метки?
Я не думаю, что Scout позволит вам добиться этого простым способом на данный момент, но это все еще возможно.
Шаг 1 - добавить столбец в
toSearchableArray()
метод. Это обеспечит индексацию данных Мейли.
Шаг 2 - изменить конфигурацию индекса, в котором ваша модель доступна для поиска, чтобы исключить
created_at
из списка доступных для поиска атрибутов . Это псевдокод и недокументированный, но он должен выглядеть примерно так:
$dummy = new Comment();
// Should resolve to an engine: https://github.com/laravel/scout/blob/f8aa3c3182fe97f56a6436fd0b28fcacfcbabc11/src/Searchable.php#L279
$engine = $dummy->searchableUsing();
// Should resolve to MeiliSearch\Endpoints\Indexes via a magic method that resolves the underlying Meili driver:
// https://github.com/laravel/scout/blob/33bbff0e3bfb1abd0ea34236c331fc17cdeac0bc/src/Engines/MeiliSearchEngine.php#L298
// ->
// https://github.com/meilisearch/meilisearch-php/blob/f25ee49b658f407af3d3f1f9a402997e7974b6bb/src/Delegates/HandlesIndex.php#L23
$index = $engine->index($dummy->searchableAs());
// https://github.com/meilisearch/meilisearch-php/blob/f25ee49b658f407af3d3f1f9a402997e7974b6bb/src/Endpoints/Delegates/HandlesSettings.php#L55
$index->updateSearchableAttributes(
['id','title', 'link', 'raw_text', 'subchan', 'nsfw']
);
Один раз
create_at
индексируется, но недоступен для поиска, вы хотите отфильтровать значение. У Мейли есть операторы для числовых значений .
Шаг 3 - выполнить индивидуальный поиск с помощью Scout:
Comment::search($query, function (Indexes $meilisearch, $query, $options) {
$options['filters'] = 'created_at>795484800';
return $meilisearch->search($query, $options);
});
Опять же, это псевдокод - я не тестировал ни одну его часть. Я был бы очень признателен, если бы Scout реализовал поддержку настройки параметров индекса при создании или предоставил метод обновления параметров, позволяющий, например, добавлять параметры конкретного драйвера в файл конфигурации.
Я потратил много часов на отладку и настройку фильтра для дат.
это не будет работать, так как предложение where принимает только два аргумента
Comment::search($query)->where('created_at', '>', 795484800)->get();
это также не будет работать, потому что переданные аргументы не являются частью двух опций, которые они поддерживают в библиотеке разведки.
Comment::search($query, function (Indexes $meilisearch, $query, $options) {
$options['filters'] = 'created_at>795484800';
return $meilisearch->search($query, $options);
});
мое решение для всех, кто пытается заставить это работать, состоит в том, чтобы использовать следующее:
$results = Event::search(
query: $request->get('query'),
callback: function (Indexes $meilisearch, $query, array $options) use ($request, $from, $to) {
$options['filter'] = "from <= 1667692800";
// dd($options);
return $meilisearch->rawSearch(
$query,
$options,
);
},
)->paginate();
надеюсь, что это поможет всем, у кого есть проблемы, так как это потратило мое утро на поиск решений, пока я не решил покопаться в коде в библиотеке.
Я решил свою проблему, используя фильтруемые атрибуты Meilisearch. Но его нужно настроить перед запуском поиска. я использовал
php artisan tinker
чтобы решить эту проблему следующим образом, вы можете написать для этого ремесленную команду.
$client = new MeiliSearch\Client('https://url_to_meilisearch_instance:7700');
$client->index('comments_index')->updateFilterableAttributes(['created_at']); // Replace your index_name
И это все. Если у вас довольно большой набор данных, вы можете запустить следующую команду, чтобы проверить статус:
$client->index('comments_index')->stats();
Если ответ содержит
isIndexing => false
ты можешь идти. Теперь вы можете запустить фильтр как обычно,
Comment::search($query)->where('created_at', '>', 795484800)->get();