0

I am trying to use redis with laravel to find similar vectors using openai embeddings.

I have an example in python that looks like this:

def search_similar_documents(self, entity_id, vector, topK=5):
        query = Query("*=>[KNN 2 @embedding $vec as score]")
        query.sort_by("score")
        query.return_fields("score")
        query.paging(0, 2)
        query.dialect(2)

        query_params = {"vec": vector}
        return self.r.ft(self.index_name).search(query, query_params)

and I try to do the same in laravel, but I have not found documentation of the library and what I try does not work.

In laravel I have this

public function searchSimilarityDocuments(int $entityId, array $vector, int $topK=2){
        $filter = '*=>[KNN '.$topK.' @embedding $vec as score]';
        // $filter = ["vec" => json_encode($vector)];
        $arguments = new SearchArguments();
        $arguments->withScores();
        $arguments->withPayloads();
        $arguments->filter($filter);

        $vector = pack('f*', ...$vector);

        $result = $this->r->ftSearch($this->indexName, $arguments, ['vec' => $vector]);
        return $result;
    }

When executing I get the following error Call to a member function toArray() on array

In this line: vendor\predis\predis\src\Command\Redis\Search\FTSEARCH.php:34

I added a log to the function to see how the data arrived but I don't understand what happens :/ I think that somehow instead of passing different arrays, it has to be an array of strings but I'm not sure.

public function setArguments(array $arguments)

    {

        [$index, $query] = $arguments;

        Log::info($arguments);

        $commandArguments = (!empty($arguments[2])) ? $arguments[2]->toArray() : [];

 

        parent::setArguments(array_merge(

            [$index, $query],

            $commandArguments

        ));

    }

y parte del log es

[2023-08-25 04:58:14] local.INFO: array (
  0 => 'conversations',
  1 => 
  Predis\Command\Argument\Search\SearchArguments::__set_state(array(
     'sortingEnum' => 
    array (
      'asc' => 'ASC',
      'desc' => 'DESC',
    ),
     'arguments' => 
    array (
      0 => 'WITHSCORES',
      1 => 'WITHPAYLOADS',
      2 => 'FILTER',
      3 => '*=>[KNN 2 @embedding $vec as score]',
    ),
  )),
  2 => 
  array (
    'vec' => '$���E�;ǻ���h���켩ǫ<�vX;��`����寍...
  ),
) 
Danilo Toro
  • 569
  • 2
  • 15

1 Answers1

0

I found the solution!!!

public function searchSimilarityDocuments(int $entityId, array $vector, int $topK=2){
        $filter = '*=>[KNN '.$topK.' @embedding $vec as score]';
        // $filter = ["vec" => json_encode($vector)];

        $arguments = new SearchArguments();
        $arguments->addReturn(1, 'score');
        $arguments->sortBy('score');
        $arguments->dialect(2);
        $arguments->limit(0, 2);

        $vector = pack('f*', ...$vector);
        // $vector = base64_encode($vector);

        $query_params = [
            'vec', $vector
        ];
        $arguments->params($query_params);

        $result = $this->r->ftSearch($this->indexName, $filter, $arguments);
        return $result;
    }
Danilo Toro
  • 569
  • 2
  • 15