You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel+Predis调用Redis搜相似向量报错:toArray()方法调用异常

问题

我希望在Laravel中通过Redis结合OpenAI Embeddings实现相似向量检索,现有可正常运行的Python示例代码如下:

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)

但编写的Laravel对应代码执行时出现错误:Call to a member function toArray() on array,错误位置在vendor\predis\predis\src\Command\Redis\Search\FTSEARCH.php第34行。添加日志查看参数传递情况后仍无法明确问题,Laravel代码及日志信息如下:

Laravel代码:

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;
    }

添加的日志代码:

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
        ));
    }

日志片段:

[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;��`����寍...
  ),
) 

请问如何解决该错误,实现Laravel中Redis相似向量检索功能?


解决方法

1. 修复参数传递逻辑

错误根源是ftSearch方法的第三个参数被当成SearchArguments对象调用toArray(),但实际传入的是普通绑定参数数组。Predis的ftSearch要求参数绑定需作为命令参数的一部分,而非单独的第三个参数。

方法一:使用SearchArguments规范传参(推荐)

public function searchSimilarityDocuments(int $entityId, array $vector, int $topK=2){
    $knnQuery = "*=>[KNN {$topK} @embedding $vec as score]";
    $arguments = new SearchArguments();
    
    // 基础查询配置
    $arguments->query($knnQuery);
    $arguments->withScores();
    $arguments->withPayloads();
    // 匹配Python示例的分页、排序、方言版本
    $arguments->limit(0, 2);
    $arguments->sortBy('score', 'DESC');
    $arguments->dialect(2);
    // 绑定向量参数(转为二进制格式)
    $arguments->parameters(['vec' => pack('f*', ...$vector)]);

    return $this->r->ftSearch($this->indexName, $arguments);
}

方法二:直接构造原生Redis命令数组

如果SearchArguments的参数绑定不生效,可直接构造符合Redis Search语法的命令数组:

public function searchSimilarityDocuments(int $entityId, array $vector, int $topK=2){
    $knnQuery = "*=>[KNN {$topK} @embedding $vec as score]";
    $packedVector = pack('f*', ...$vector);
    
    $commandArgs = [
        $this->indexName,
        $knnQuery,
        'WITHSCORES',
        'WITHPAYLOADS',
        'DIALECT', '2',
        'LIMIT', 0, 2,
        'SORTBY', 'score', 'DESC',
        'PARAMS', 2, 'vec', $packedVector
    ];

    return $this->r->executeRaw($commandArgs);
}

2. 修复日志代码的类型判断问题

自定义的setArguments错误地假设第三个参数是对象,修改为兼容数组和对象的逻辑:

public function setArguments(array $arguments)
{
    [$index, $query] = $arguments;
    Log::info($arguments);
    
    $commandArguments = [];
    if (!empty($arguments[2])) {
        $commandArguments = is_object($arguments[2]) ? $arguments[2]->toArray() : $arguments[2];
    }

    parent::setArguments(array_merge(
        [$index, $query],
        $commandArguments
    ));
}

3. 关键注意事项

  • 必须指定DIALECT 2:Redis Search的KNN参数绑定语法仅在dialect 2及以上版本支持,需和Python示例保持一致。
  • 向量格式匹配:使用pack('f*', ...$vector)将浮点数组转为二进制格式,确保和Redis中存储的向量编码一致。
  • 参数绑定格式:通过PARAMS关键字传递参数,格式为PARAMS [键值对数量] [键1] [值1] [键2] [值2]。

内容的提问来源于stack exchange,提问作者Danilo Toro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 12:12:23