meilisearch / meilisearch-php

PHP wrapper for the Meilisearch API

Home Page:https://meilisearch.com

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot set limit to 0 due to falsy reset to default

JellowGerard opened this issue · comments

Description
I have the need to get the total number of documents matching a certain query. However, I don't want to retrieve the matching results, as I don't need them at that point, and they will only slow things down. As such, I set the limit of the DocumentQuery to 0.

Expected behavior
I expect to get no hits, but still the required info on the total hits.

Current behavior
Due to this code: 'limit' => $this->limit ?? null,, 0 is considered falsy, resulting in the limit to be reset to null.

Environment (please complete the following information):

  • OS: MacOS
  • Meilisearch version: v.1.0.2
  • meilisearch-php version: v1.0.0
commented

I dont think this null coalescing operator does what you experience

<?php
$a = null;
$b = 0;
echo $a ?? "a is null";
echo "\n";
echo $b ?? "b is 0";
echo "\n";
echo $c ?? "c does not exist";

output

a is null
0
c does not exist

You can see it live here

as you see the 0 is not considered falsy (if that is the case you should see that b is 0 in the output.

The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not null; otherwise it returns its second operand. doc

the issue is something else.

Hi @JellowGerard, I'm trying to reproduce your issue with a test case:

    public function testGetDocumentsWithZero(): void
    {
        // just adding documents to an index.
        $index = $this->createEmptyIndex($this->safeIndexName('movies'));
        $response = $index->addDocuments(self::DOCUMENTS);
        $index->waitForTask($response['taskUid']);

        // requesting as you explained.
        $response = $index->getDocuments((new DocumentsQuery())->setLimit(0));

        // asserting that I get no document in the results array but still the total.
        $this->assertEquals($response->getTotal(), count(self::DOCUMENTS));
        $this->assertEquals($response->getResults(), []);
    }

And it works as expected. Can you enlighten me on your use case? If you can tweak this code, it could be even better.

Sorry for the late reply. I went over it line by line, and found the root cause of the issue, which is different than I initially thought.
The issue actually lies with the Laravel Scout implementation, rather than the meilisearch-php implementation.

For those of you experiencing similar issues, here is what I found and how to work around it:
In the Scout MeilisearchEngine class, every time you call the performSearch function, the $searchParams array is set using the array_filter function, which filters out all "empty" values from the array. In this function, it filters out 'hitsPerPage' => 0, since 0 is considered falsy, meaning melisearch never receives the desired limit of 0.

For my implementation, I fixed this by overwriting the MeilisearchEngine->search function, and providing a second argument for the array_filter function, which specifically checks for null, empty strings, or empty arrays, but leaves zero alone.

tl;dr: not a bug in meilisearch-php after all, but rather an "unwanted feature" in the Laravel Scout implementation of Meilisearch.