创建新的索引并在同一步骤中添加数据与seen in the docs相同.

但是,当我试图添加数据到现有的索引,我得到以下异常.

Ehann\RediSearch\Exception\FieldNotInSchemaException

The field is not a property in the index

以下是我的代码:

$adapter = new PredisAdapter();

$host = config('database.redis.default.host');
$port = config('database.redis.default.port');
$database = config('database.redis.default.database');
$password = config('database.redis.default.password');
$redis = $adapter->connect($host, $port, $database, $password);

$bookIndex = new Index($redis, 'books');

$bookIndex->add([
    new TextField('title', 'Tale of Two Cities'),
    new TextField('author', 'Charles Dickens'),
    new NumericField('price', 9.99),
    new NumericField('stock', 231),
]);

我研究了redisearch-php的源代码,似乎如果不总是添加带有addTextField或其他的字段,这是不可能实现的.但在我看来,这似乎不太现实.我想我必须在创建索引时添加一次字段.我说错了吗?

getFields方法(用于某些方法,如makeDocument)从Index获取对象变量,但如果事先未手动添加,则字段相关对象变量不在实例中.

供应商/ethanhann/redisearch-php/src/index.php

/**
 * @return array
 */
protected function getFields(): array
{
    $fields = [];
    foreach (get_object_vars($this) as $field) {
        if ($field instanceof FieldInterface) {
            $fields[$field->getName()] = clone $field;
        }
    }
    return $fields;
}

/**
 * @param string $name
 * @param float $weight
 * @param bool $sortable
 * @param bool $noindex
 * @return IndexInterface
 */
public function addTextField(string $name, float $weight = 1.0, bool $sortable = false, bool $noindex = false): IndexInterface
{
    $this->$name = (new TextField($name))->setSortable($sortable)->setNoindex($noindex)->setWeight($weight);
    return $this;
}

/**
 * @param string $name
 * @param bool $sortable
 * @param bool $noindex
 * @return IndexInterface
 */
public function addNumericField(string $name, bool $sortable = false, bool $noindex = false): IndexInterface
{
    $this->$name = (new NumericField($name))->setSortable($sortable)->setNoindex($noindex);
    return $this;
}

/**
 * @param string $name
 * @return IndexInterface
 */
public function addGeoField(string $name, bool $noindex = false): IndexInterface
{
    $this->$name = (new GeoField($name))->setNoindex($noindex);
    return $this;
}

推荐答案

所以,我今天玩弄了这个.我认为你是对的.您每次都必须重新声明该模式,即使它在redis上已经存在.我看不到任何用于从redis中提取模式的函数,这有点令人费解.

您可以在$bookIndex->;info()函数的输出中看到字段,但它不会为您设置模式.

我对这个问题的解决方案是创建一个处理设置索引对象的类,这样您就不必一直这么做了.大概是这样的:

class book_index
{
    private $index;

    public function __construct($redis)
    {
        $this->index = new Index($redis);
        $this->index->setIndexName("book");
        $this->set_schema();
    }

    private function set_schema(){
        $this->index->addTextField('title')
            ->addTextField('author')
            ->addNumericField('price')
            ->addNumericField('stock');

        // attempt to create the index, I couldn't find any function to check if it already exists
        // so catching the failure or using info() and catching the exception on that was the only way
        try {
            $this->index->create();
        }catch (Ehann\RediSearch\Exceptions\RediSearchException $exception){
            error_log("book index already exists.");
            error_log( $exception->getMessage());
        }
    }

    public function get_index(){
        return $this->index;
    }

    public static function get($redis){
        $obj = new self($redis);
        return  $obj->get_index();
    }
}

然后您的代码将如下所示:

include_once ("book_index.php"); // include the class file 
$adapter = new PredisAdapter();

$host = config('database.redis.default.host');
$port = config('database.redis.default.port');
$database = config('database.redis.default.database');
$password = config('database.redis.default.password');
$redis = $adapter->connect($host, $port, $database, $password);

$bookIndex = book_index::get($redis);

$bookIndex->add([
    new TextField('title', 'Tale of Two Cities'),
    new TextField('author', 'Charles Dickens'),
    new NumericField('price', 9.99),
    new NumericField('stock', 231),
]);

您可以将更多的功能移到类中,但我只是试着保持简单.

Php相关问答推荐

PHP邮件表单无法识别重音/特殊字符

如何使用`preg_replace`删除重复的空格字符

使用箭头函数语法时,在回调范围内无法访问变量变量(警告:未定义的变量)

将变体设置字段添加到WooCommerce中的特定变量产品

为什么在我的PHP联系人脚本中开机自检后出现未定义变量错误?

使用列入黑名单的单词和自定义业务逻辑的组合将特定的子字符串包装在HTML标记中

在PHP中循环访问多维数组,并按组显示内容

如何在execute语句中使用存储过程参数?

防止在WordPress短代码中显示重复产品并请求代码更正

按类别层次 struct 过滤 Laravel 集合

PHP访问子数组列表出错结果和长度

Woocommerce 相关产品按其类别或排名数学主要类别

在WooCommerce中显示 checkout 的高级自定义字段(Advanced Custom Fields)并保存其值

使用 Process facade 在外部 Laravel 项目上运行 Artisan 命令会返回主项目的数据库错误

PHP 日期格式:ISO8601 与 ISO8601_EXPANDED

输出每个可能的产品选项

为什么 AJAX 请求没有通过 is_ajax_request() codeigniter 的条件?

使用 PHP ImageMagick 库将 pdf 文件的前 n 页转换为单个 png 图像文件

fopen 功能不断向我发送我重新加载网页时已发布的重复版本的表单

复杂的mysql查询问题