Laravel Scout toSearchableArray attribute is not filterable
Asked Answered
B

1

7

I've been doing some testing with laravel scout and according to the documentation (https://laravel.com/docs/8.x/scout#configuring-searchable-data), I've mapped my User model as such:

 /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $data = $this->toArray();
        return array_merge($data, [
            'entity' => 'An entity'
        ]);
    }

Just for the sake of testing, this is literally what I came down to on the debugging.

After importing the User model with this mapping, I can see on the meilisearch dashboard it is indeed showing the user data + the entity = 'An entity'.

However, when applying this:

User::search('something')->where('entity', 'An entity')->get() It produces the following error:

"message": " --> 1:1\n  |\n1 | entity=\"An entity\"\n  | ^----^\n  |\n  = attribute `entity` is not filterable, available filterable attributes are: ",
"exception": "MeiliSearch\\Exceptions\\ApiException",
"file": "/var/www/api/vendor/meilisearch/meilisearch-php/src/Http/Client.php",

Tracing back to view the 'filterable attributes', I've ended at the conclusion that:

$client = app(\MeiliSearch\Client::class);
dump($client->index('users')->getFilterableAttributes()); // Returns []
$client->index('users')->updateFilterableAttributes(['entity']);
dump($client->index('users')->getFilterableAttributes()); // Returns ['entity']

Forcing the updateFilterableAttributes now allows me to complete the search as intended, but I don't feel this should be the regular behaviour? If its mapped on the searchableArray, it should be searchable? What am I not understanding and what other approaches are there to achieve this goal?

Bywaters answered 8/2, 2022 at 16:48 Comment(1)
Ever found what was the issue?Viddah
M
2

This is actually not an issue but a requirement of meilisearch in particular. Scout under the hood uses different drivers for indexing - "algolia", "meilisearch", "database", "collection" and even "null", all of them have different indexing methods unifing of which would be troublesome and inefficient for scout I believe.

So filtering or a faceted search, as meilisearch refers to it, requires us to establish filtering criteria first, which is empty by default for document (models in laravel) fields.

Quoting from the docs:

This step is mandatory and cannot be done at search time. Filters need to be properly processed and prepared by Meilisearch before they can be used.

Updating filterableAttributes requires recreating the entire index. This may take a significant amount of time depending on your dataset size.

For more info please refer to meilisearch official docs https://docs.meilisearch.com/learn/advanced/filtering_and_faceted_search.html

Mitsue answered 5/4, 2022 at 5:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.