Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

attributesToRetrieve: array_flip(): Can only flip string and integer values, entry skipped #750

Closed
pedzed opened this issue Jul 3, 2023 · 8 comments · Fixed by #751
Closed

Comments

@pedzed
Copy link

pedzed commented Jul 3, 2023

Scout Version

10.2.2

Scout Driver

Meilisearch

Laravel Version

10.14.1

PHP Version

8.2.4

Database Driver & Version

No response

SDK Version

1.2.0

Meilisearch CLI Version

No response

Description

I'm getting the following error:

array_flip(): Can only flip string and integer values, entry skipped

  at vendor/laravel/scout/src/Engines/MeilisearchEngine.php:274

I'm probably doing something wrong, but either way, there is something wrong with the library. Perhaps missing precondition checks?

If the mistake is on my side, then I expect an exception to be thrown with a clear description of what's wrong.

Steps To Reproduce

In MyModel, have something like:

public function toSearchableArray(): array
{
    return [
        'field1' => $this->field1,
        'field2' => $this->field2,
    ];
}

In scout/config.php, have something like:

// ...

'meilisearch' => [
    // ...
    'index-settings' => [
        MyModel::class => [
            'filterableAttributes' => [
                'field1',
                'field2',
            ],
        ],
    ],
],

// ...

Then update those indexes:

artisan scout:sync-index-settings

Finally try searching with:

MyModel::search($query, function (Indexes $meilisearch, string $query, array $options) {
    $options['attributesToRetrieve'] = ['field1', 'field2'];

    return $meilisearch->search($query, $options);
})->first();

Now expect the error:

array_flip(): Can only flip string and integer values, entry skipped

Remove this line and the error goes away:

$options['attributesToRetrieve'] = ['field1', 'field2'];
@mmachatschek
Copy link
Contributor

mmachatschek commented Jul 3, 2023

@pedzed you should add the id (or whatever your unique identifier on the model is) field to the attributesToRetrieve list.

This is a very new feature of the meilisearch SDK, so we didn't find the time to add this yet.

So what happens is, that we pluck the unique identifier in the meilisearch index from the result object. But that exact key is missing in your attributesToRetrieve config and therefore in the result payload of the search request to meilisearch.

Will add an improvement to this

@pedzed
Copy link
Author

pedzed commented Jul 3, 2023

Seemingly, id gets automatically added to toSearchableArray(), which is what I tried to get rid of with attributesToRetrieve in the first place. But I'm just toying around.

Requiring id and throwing an exception otherwise would suffice.

@mmachatschek
Copy link
Contributor

mmachatschek commented Jul 3, 2023

the unique identifier on the search index needs to be set in the payload. Otherwise meilisearch and laravel scout could never connect a search result with the according dataset in the database.

If you need to send a custom search query to meilisearch and just use the result of the meilisearch payload, you could probably get the meilisearch instance from the service provider and call the meilisearch SDK yourself.

$this->app->singleton(Meilisearch::class, function ($app) {
$config = $app['config']->get('scout.meilisearch');
return new Meilisearch(
$config['host'],
$config['key'],
clientAgents: [sprintf('Meilisearch Laravel Scout (v%s)', Scout::VERSION)],
);
});

@pedzed
Copy link
Author

pedzed commented Jul 3, 2023

What I'd like to do is search in field1 and field2 only, i.e. with exception of id.

I'm now using

$options['filter'] = 'field1="' . $query . '" OR field2="' . $query . '"';

However, I'm not sure if this is "safe", as one may tamper with the filter like with SQL injection.

@pedzed pedzed changed the title array_flip(): Can only flip string and integer values, entry skipped attributesToRetrieve: array_flip(): Can only flip string and integer values, entry skipped Jul 3, 2023
@mmachatschek
Copy link
Contributor

mmachatschek commented Jul 3, 2023

@pedzed Ahh..I mixed the attributesToRetrieve functionality with the new searchable fields setting at search time which is coming up in v1.3.0 meilisearch/meilisearch#3772

I think what you are searching for is https://www.meilisearch.com/docs/reference/api/settings#searchable-attributes
The people over at meilisearch discord https://discord.com/invite/meilisearch are always happy to help and give you answers if you need to dig in further

@driesvints
Copy link
Member

@mmachatschek thanks! Can we close this one?

@mmachatschek
Copy link
Contributor

@driesvints I'll try to send a PR for the attributesToRetrieve which should at least have the scoutkey in the payload.

@mmachatschek
Copy link
Contributor

@pedzed

as info from my PR

Fixes occasions with meilisearch where users can set options on the Builder class like attributesToRetrieve which would restrict the search engine to include the unique identifiers on the search result.

Unfortunately if users customize their search engine calls this issue would still be possible as we have no control over the search result provided by the user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants