meilisearch / meilisearch-php

PHP wrapper for the Meilisearch API

Home Page:https://meilisearch.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Unknown parameter `primaryKey`: expected one of `offset`, `limit`, `fields`

pedzed opened this issue · comments

commented

Description
I am using Laravel Sail (Docker) and my unit tests are suddenly failing. I'm not yet sure where the problem exactly lies.

Failed to connect to 127.0.0.1 port 7700 after 0 ms: Connection refused for "http://127.0.0.1:7700/indexes/MY_INDEXES/documents?primaryKey=id".

Opening the link gives the following JSON:

{
    "message": "Unknown parameter `primaryKey`: expected one of `offset`, `limit`, `fields`",
    "code": "bad_request",
    "type": "invalid_request",
    "link": "https://docs.meilisearch.com/errors#bad_request"
}

Environment

  • OS: macOS
  • PHP v8.2.3
  • Laravel v10.1.5
  • Laravel Sail v1.21.0
  • Laravel Scout v9.8.1
  • Meilisearch Docker image v1.0.2
  • meilisearch-php version: ^1.0

Hi @pedzed

One of the breaking changes we introduced in the v1 on the Meilisearch engine was the removal of the acceptance of primaryKey during the update documents.
As you can check it here: https://docs.meilisearch.com/reference/api/documents.html#add-or-update-documents

If you try to set the primary key after having added documents to the index, the task will return an error.

So if you handle your meili calls to remove the primaryKey option when the index is already built, you will fix the error.

Let me know if it works or not :) And feel free to reopen if needed!

commented

I think this is related to my Laravel Scout version. Scout updates for Meilisearch v1.0 seem to be merged (laravel/scout#678) into Scout v10, but it is not yet released. I'm using the latest released Scout version, which is v9.8.1 as of now, but I seem to need v10.

I see you're involved with Scout as well. Do you know more about this, @brunoocasali?

Oh I see, so can you try with the scout v10 branch to check if it solves your problem?

I only touched the code to review the meili integration, but I don't know when it will be released, sorry :/

commented

Manually changing ^9.8 to ^10.0 in composer.json worked to upgrade:

// composer.json
"laravel/scout": "^10.0",
$ composer update
// composer.lock
"name": "laravel/scout",
"version": "10.x-dev",

Although some other issues are solved (e.g. artisan scout:delete-all-indexes), I'm still getting the same problem as described at the beginning.

Can you share part of the code where you use ->updateDocuments()? Unless you don't have any explicitly call to it..

commented

I'm not using that directly, no. I suppose Laravel Scout handles that with the following command:

$ artisan scout:import "App\Models\MyModel"

However, even with a fresh (and empty) Meilisearch database, it gives me the aforementioned problem.

Removing the Searchable trait from my model gets rid of the error (which consequently makes searching unusable of course):

<?php

namespace App\Models;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class MyModel extends Model
{
    // use Searchable;

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

Actually I misread the error message, this came from a ->getDocuments call, do you have any calls of this method?

Hi @pedzed did you find out how to solve the issue? Do you still have the issue?

commented

Yes, unfortunately, I still stumble upon the same issue.

Did you see this message?

Actually I misread the error message, this came from a ->getDocuments call, do you have any calls of this method?

commented

I don't use it, unless Scout uses it under the hood.

Perhaps I'll try reproducing it later with a fresh Laravel installation. Maybe that would narrow down the problem further.

commented

Hm, (un?)fortunately, I cannot reproduce this on a fresh project setup, so the problem lies deeper.

I'll document my steps here anyway.

  1. Install Laravel with Sail setup:
    composer create-project laravel/laravel example-app
    cd example-app
    composer require laravel/sail --dev
    php artisan sail:install --with mariadb,meilisearch
    ./vendor/bin/sail up -d
    ./vendor/bin/sail artisan migrate
  2. Use a working testing database by changing the following line in phpunit.xml:
    <env name="DB_DATABASE" value="testing"/>
    Possibly to:
    <!-- <env name="DB_DATABASE" value="testing"/> -->
  3. Replace the following line from tests/Unit/ExampleTest.php:
    use PHPUnit\Framework\TestCase;
    With:
    use Tests\TestCase;
  4. Check tests to be passing:
    ./vendor/bin/sail test
  5. Add some model-interacting test to tests/Unit/ExampleTest.php:
    public function test_user_model(): void
    {
        \App\Models\User::truncate();
        \App\Models\User::factory(3)->create();
        $this->assertCount(3, \App\Models\User::all());
    }
  6. Check tests to be (still) passing:
    ./vendor/bin/sail test
  7. Install and setup Scout for Meilisearch:
    composer require laravel/scout
    php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
    composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle
  8. Add search functionality to app/Models/User.php:
    // ...
    use Laravel\Scout\Searchable;
    
    class User extends Authenticatable
    {
        // ...
        use Searchable;
    
        // ...
    
        /**
         * Get the indexable data array for the model.
         *
         * @return array<string, mixed>
         */
        public function toSearchableArray(): array
        {
            return [
                'id' => $this->id,
                'name' => $this->name,
                'email' => $this->email,
            ];
        }
    }
  9. Check tests to be still passing:
    ./vendor/bin/sail test

I expected it to fail by now, but it passes, and therefore, I cannot reproduce my problem from a fresh installation.

commented

At last! I found the issue.

In my .env.testing file I used the following variables:

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

Whilst going to http://127.0.0.1:7700 works locally (i.e. for the Meilisearch dashboard), Meilisearch is run inside a Sail (Docker) container. MEILISEARCH_HOST should therefore be http://meilisearch:7700.

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://meilisearch:7700
MEILISEARCH_KEY=masterKey

Perhaps this can be communicated better to the developer, because this was not an obvious find. One would not think that

Unknown parameter primaryKey: expected one of offset, limit, fields

has anything to do with a connection issue.

I must remind though, that I got this error after following the link provided in the unit test error message:

Failed to connect to 127.0.0.1 port 7700 after 0 ms: Connection refused for "http://127.0.0.1:7700/indexes/my_index_here/documents?primaryKey=id"

So both instances were using different versions of Meilisearch right?

commented

I'm not sure how Meilisearch works behind the hood, but as far as I know, I have only one version. It just seems to act differently based on local/"remote" access.

If you run the version check on both environments https://docs.meilisearch.com/reference/api/version.html#get-version-of-meilisearch do you have the same results?

commented
curl -X GET 'http://127.0.0.1:7700/version'
{
    "commitSha":"572608c121d960cdf48c2c289a6dfd3dc834873a",
    "commitDate":"2023-02-23T13:52:56+00:00",
    "pkgVersion":"1.0.2"
}

http://meilisearch:7700/version does not work directly. But the issue lied in using 127.0.0.1:7700(localhost:7700), which is indeed correctly v1.0.2. The Meilisearch dashboard does work though, just not using my web application, running on Sail/Docker in development.

The related Docker settings, I believe, are:
https://github.com/laravel/sail/blob/3042ff8cf403817c340d5a7762b2d32900239f46/stubs/meilisearch.stub#L1-L12

What could have happened in your case was that you were running two instances of meilisearch (one with docker) and another directly in your host.
Meilisearch does not handle accesses differently for Meili, and it does not matter if you're calling localhost, over the wire, or using an SDK.

This used to happen to me because I switch SDK environments 10x a day, so it was common to have this mismatch and, consequently, some weird behavior.

What I would like to have in the SDKs was a way to verify which meili version the developer is running and alert them if it was not the expected one.

Unfortunately, I couldn't reproduce this behavior either, so we may need to wait for someone else with the same issue. Unless, of course, you find a new tip.

Take care!