scout: 0.21 meilisearch breaking changes

  • Scout Version: v9.2.8
  • Scout Driver: MeiliSearch
  • Laravel Version: 8.58.0
  • PHP Version: 8.0.9
  • Database Driver & Version: mySql 8.0.25 for macos11.3 on x86_64 (Homebrew)

Description:

Since last changes on meilisearch, filters are not working. I have seen changes and updated code, so instead of ‘filters’ now is a ‘filter’ as a index

MeiliSearch\Exceptions\ApiException
Json deserialize error: unknown field `filters`, expected one of `q`, `offset`, `limit`, `attributesToRetrieve`, `attributesToCrop`, `cropLength`, `attributesToHighlight`, `matches`, `filter`, `facetsDistribution` at line 1 column 31

When I replace it with filter, I am getting error that my field cant be indexed, as its not indexable.

--> 1:1 | 1 | active=1 | ^----^ | = attribute `active` is not filterable, available filterable attributes are: (View: 

Meili search documentation says this:

“By default, filterableAttributes is empty. This means that filters do not work without first explicitly adding attributes to the filterableAttributes list.”

I cant find a way to add attributes to filterableAttributes list. I suppose I can manually ‘curl’ update, but this just is not a solution. Anyone has idea how to make filterableAttributes?

Steps To Reproduce:

ad filter and and search using filter

Model::search(
            $query,
            function ($meilisearch, $query, $options) {
                // $options['filters'] = 'active=1'; // breaking change in meilisearch 0.21
                 // $options['filter'] = 'active=1'; // change it to filter, without s
                return $meilisearch->search($query, $options);
            }
        )
        ```

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 2
  • Comments: 15 (9 by maintainers)

Most upvoted comments

@Tiththa The problem with that approach is it is going to hit the index every single time toSearchabbleArray is invoked. If you’re importing a lot of records this is going to fail as eventually it’ll overwhelm Meilisearch and you’ll get HTTP timeouts. A better approach is to make a scout:setup command and create the indexes and update the filterable attributes just once, then update your records with scout:import

@Tiththa The problem with that approach is it is going to hit the index every single time toSearchabbleArray is invoked. If you’re importing a lot of records this is going to fail as eventually it’ll overwhelm Meilisearch and you’ll get HTTP timeouts. A better approach is to make a scout:setup command and create the indexes and update the filterable attributes just once, then update your records with scout:import

@joecampo Thank you so much for the recommendation. It is a clean approach. Going to try it out. Thanks once again

Here how i did it to make it work:

Model.php

use MeiliSearch\Client;
.....

public function toSearchableArray(): array {

    $data = $this->only(['id']);
    // add additional fields from profile (or related models).    

    $url = config('scout.meilisearch.host');
    $hit = new Client($url);
    $hit->index($this->searchableAs())->updateFilterableAttributes(['active']);
    return $data;
}
```

With this changes, I have re run my imports and got all working

@driesvints Thank you all guys for the follow-ups.

Meilisearch doesn’t support filters without fist specifying the filterable columns first, anymore. Before 0.21 they had filters and facet filters. Filters have been removed and facet filters is now named filter.

It is thus up to the user to add the columns to filter on, to their index settings, or to just simply not use the where function.

This exactly is a problem. In Meilisearch-php is a method on website documentation, where you can set filters.

$client->index('movies')->updateFilterableAttributes([
  'genres',
  'director'
]);

Cant you in scout make updateFilterableAttributes to be used with MeiliEngine?

@georgeboot how to use “where” or to make. changes in filter settings? I see an option to send Curl, but this is not really good solution to do manually. Prefer some scout method we can call and send it to meilie to set filterableAttributes.

ON meilisearch slack channel, I got asked if I have some settings in laravel for meili search. We don’t have it.

Using where throws the same error:

Model::search(
            $query,
            function ($meilisearch, $query, $options) {
                // $options['filter'] = 'active=1'; // breaking change in meilisearch 0.21
                return $meilisearch->search($query, $options);
            }
        )->query(function ($builder) {
            $builder->with('business')
                    ->with('industry')
                    ->with('sector')
                    ->with('position')
                    ->with('country');
        })->where('active', 1);

THrows:

MeiliSearch\Exceptions\ApiException
Json deserialize error: unknown field `filters`, expected one of `q`, `offset`, `limit`, `attributesToRetrieve`, `attributesToCrop`, `cropLength`, `attributesToHighlight`, `matches`, `filter`, `facetsDistribution` at line 1 column 21

Thanks for the explanation @curquiza. I can agree that if the OP makes a conscience choice of upgrading their Meilisearch binary that they also need to review the Meilisearch changelog.

@nezaboravi I hope you understand from the above why this isn’t a Scout issue and that you should always review the breaking changes of the binary.

I’ve sent in a PR to the docs for this: https://github.com/laravel/docs/pull/7286