glukkkk/sphinxql-query-builder

用于 SphinxQL 的 PHP 查询构建器。使用 MySQLi 连接到 Sphinx 服务器。

4.0.2 2024-08-28 14:46 UTC

README

Build Status Latest Stable Version Latest Unstable Version Total Downloads

关于

这是一个用于与 SphinxQL 一起工作的 SphinxQL 查询构建器,SphinxQL 是与 Sphinx 搜索引擎及其分支 Manticore 一起使用的 SQL 方言。它映射了 SphinxQL 参考 中列出的大多数功能,并且通常比可用的 Sphinx API 更快。

此查询构建器除了 PHP 7.1 或更高版本、\MySQLi 扩展、PDO 以及 Sphinx/Manticore 外没有依赖项。

缺少方法?

SphinxQL 发展非常迅速。

大多数新功能都是静态单行函数,如 SHOW PLUGINS。我们将避免尝试跟上这些方法,因为它们可以直接调用((new SphinxQL($conn))->query($sql)->execute())。您可以根据需要提交支持这些方法的拉取请求。

如果通过此库无法访问任何功能,请打开新问题或发送拉取请求。

代码质量

该包中的大多数方法都已进行单元测试。

唯一未完全测试的方法是 Helper,它们主要是 SQL 字符串的简单缩写。

如何贡献

拉取请求

  1. 克隆 SphinxQL 查询构建器存储库
  2. 为每个功能或改进创建新分支
  3. 从每个分支向 master 分支提交拉取请求

将新功能或改进分开到不同的功能分支,并为每个分支发送拉取请求非常重要。这样可以让我单独审查和合并新功能或改进。

样式指南

所有拉取请求都必须遵循 PSR-2 标准。

单元测试

所有拉取请求都必须附带通过单元测试和完整的代码覆盖率。SphinxQL 查询构建器使用 phpunit 进行测试。

了解 PHPUnit

安装

这是一个 Composer 包。您可以使用以下命令安装此包:composer require foolz/sphinxql-query-builder

用法

以下示例将省略命名空间。

<?php
use Foolz\SphinxQL\SphinxQL;
use Foolz\SphinxQL\Drivers\Mysqli\Connection;

// create a SphinxQL Connection object to use with SphinxQL
$conn = new Connection();
$conn->setParams(array('host' => 'domain.tld', 'port' => 9306));

$query = (new SphinxQL($conn))->select('column_one', 'colume_two')
    ->from('index_ancient', 'index_main', 'index_delta')
    ->match('comment', 'my opinion is superior to yours')
    ->where('banned', '=', 1);

$result = $query->execute();

驱动程序

我们支持以下数据库连接驱动程序

  • Foolz\SphinxQL\Drivers\Mysqli\Connection
  • Foolz\SphinxQL\Drivers\Pdo\Connection

连接

  • $conn = new Connection()

    创建一个新的连接实例,用于使用以下方法或 SphinxQL 类。

  • $conn->setParams($params = array('host' => '127.0.0.1', 'port' => 9306))

    设置用于建立服务器连接的连接参数。支持的参数:'host'、'port'、'socket'、'options'。

  • $conn->query($query)

    在服务器上执行查询。返回包含查询结果的 ResultSet 对象。

Connection 类中还有更多方法可用,但通常不需要,因为这些操作是自动处理的。

SphinxQL

  • new SphinxQL($conn)

    创建一个用于生成查询的 SphinxQL 实例。

绕过查询转义

通常,您可能需要调用和运行不应在查询中转义的SQL函数。您可以通过将查询包装在\Expression中来绕过查询转义。

  • SphinxQL::expr($string)

    返回未转义的字符串。

查询转义

在某些情况下,输入必须在SQL语句中转义。以下函数用于处理查询所需的任何转义。

  • $sq->escape($value)

    返回转义后的值。这是通过\MySQLi::real_escape_string()函数处理的。

  • $sq->quoteIdentifier($identifier)

    为标识符添加反引号引号。对于数组元素,使用$sq->quoteIdentifierArray($arr)

  • $sq->quote($value)

    为值添加引号并转义它。对于数组元素,使用$sq->quoteArr($arr)

  • $sq->escapeMatch($value)

    转义用于MATCH的字符串。

  • $sq->halfEscapeMatch($value)

    转义用于MATCH的字符串。允许以下字符:-|"

    有关更多信息,请参阅$sq->match()

SELECT

  • $sq = (new SphinxQL($conn))->select($column1, $column2, ...)->from($index1, $index2, ...)

    开始一个SELECT查询语句。如果没有指定列,则默认使用*$column1$index1都可以是数组。

INSERT, REPLACE

这将返回一个包含受影响的行数的INT

  • $sq = (new SphinxQL($conn))->insert()->into($index)

    开始一个INSERT

  • $sq = (new SphinxQL($conn))->replace()->into($index)

    开始一个REPLACE

  • $sq->set($associative_array)

    插入一个关联数组,其中键是列,值是对应列的值。

  • $sq->value($column1, $value1)->value($column2, $value2)->value($column3, $value3)

    单独设置每个列的值。

  • $sq->columns($column1, $column2, $column3)->values($value1, $value2, $value3)->values($value11, $value22, $value33)

    允许在指定的列中插入多个值数组。

    $column1$index1都可以是数组。

UPDATE

这将返回一个包含受影响的行数的INT

  • $sq = (new SphinxQL($conn))->update($index)

    开始一个UPDATE

  • $sq->value($column1, $value1)->value($column2, $value2)

    使用相应的值更新所选列。

  • $sq->set($associative_array)

    插入关联数组,其中键是列,相应的值是列值。

DELETE

将返回一个包含一个INT数组的数组,该数组是删除的行数。

  • $sq = (new SphinxQL($conn))->delete()->from($index)->where(...)

    开始一个DELETE

WHERE

  • $sq->where($column, $operator, $value)

    标准的WHERE,扩展为与Sphinx筛选器和全文一起使用。

    <?php
    // WHERE `column` = 'value'
    $sq->where('column', 'value');
    
    // WHERE `column` = 'value'
    $sq->where('column', '=', 'value');
    
    // WHERE `column` >= 'value'
    $sq->where('column', '>=', 'value');
    
    // WHERE `column` IN ('value1', 'value2', 'value3')
    $sq->where('column', 'IN', array('value1', 'value2', 'value3'));
    
    // WHERE `column` NOT IN ('value1', 'value2', 'value3')
    $sq->where('column', 'NOT IN', array('value1', 'value2', 'value3'));
    
    // WHERE `column` BETWEEN 'value1' AND 'value2'
    // WHERE `example` BETWEEN 10 AND 100
    $sq->where('column', 'BETWEEN', array('value1', 'value2'));

    请注意,目前还不支持也不实现SphinxQL方言中的OR和括号。

MATCH

  • $sq->match($column, $value, $half = false)

    在全文字段中进行搜索。可以在同一个查询中多次使用。列可以是数组。值可以是表达式以绕过转义(并使用您自己的自定义解决方案)。

    <?php
    $sq->match('title', 'Otoshimono')
        ->match('character', 'Nymph')
        ->match(array('hates', 'despises'), 'Oregano');

    默认情况下,所有输入都进行了转义。需要使用SphinxQL::expr($value)来绕过默认的转义和引号函数。

    $half参数,如果设置为true,则不会转义并允许使用以下字符:-|"。如果您计划使用此功能并将其公开到公共接口,则建议将查询包装在try catch块中,因为字符顺序可能会抛出查询错误。

    <?php
    use Foolz\SphinxQL\SphinxQL;
    
    try
    {
        $result = (new SphinxQL($conn))
            ->select()
            ->from('rt')
            ->match('title', 'Sora no || Otoshimono', true)
            ->match('title', SphinxQL::expr('"Otoshimono"/3'))
            ->match('loves', SphinxQL::expr(custom_escaping_fn('(you | me)')));
            ->execute();
    }
    catch (\Foolz\SphinxQL\DatabaseException $e)
    {
        // an error is thrown because two `|` one after the other aren't allowed
    }

GROUP, WITHIN GROUP, ORDER, OFFSET, LIMIT, OPTION

  • $sq->groupBy($column)

    GROUP BY $column

  • $sq->withinGroupOrderBy($column, $direction = null)

    WITHIN GROUP ORDER BY $column [$direction]

    方向可以省略为null,也可以是ASCDESC(不区分大小写)。

  • $sq->orderBy($column, $direction = null)

    ORDER BY $column [$direction]

    方向可以省略为null,也可以是ASCDESC(不区分大小写)。

  • $sq->offset($offset)

    LIMIT $offset, 9999999999999

    设置偏移量。由于 SphinxQL 不支持 OFFSET 关键字,因此将 LIMIT 设置为一个极高的数值。

  • $sq->limit($limit)

    LIMIT $limit

  • $sq->limit($offset, $limit)

    LIMIT $offset, $limit

  • $sq->option($name, $value)

    OPTION $name = $value

    为查询设置 SphinxQL 选项,如 max_matchesreverse_scan

事务

  • (new SphinxQL($conn))->transactionBegin()

    开始一个事务。

  • (new SphinxQL($conn))->transactionCommit()

    提交一个事务。

  • (new SphinxQL($conn))->transactionRollback()

    回滚一个事务。

执行和编译

  • $sq->execute()

    编译、执行并 返回 包含查询结果的 ResultSet 对象。

  • $sq->executeBatch()

    编译、执行并 返回 包含多查询结果的 MultiResultSet 对象。

  • $sq->compile()

    编译查询。

  • $sq->getCompiled()

    返回最后一个编译的查询。

  • $sq->getResult()

    返回 ResultSetMultiResultSet 对象,具体取决于是否执行了单查询或多查询。

多查询

  • $sq->enqueue(SphinxQL $next = null)

    排队查询。如果提供了 $next,则将其附加并返回,否则返回一个新的 SphinxQL 对象。

  • $sq->executeBatch()

    返回一个包含多查询结果的 MultiResultSet 对象。

<?php
use Foolz\SphinxQL\SphinxQL;

$result = (new SphinxQL($this->conn))
    ->select()
    ->from('rt')
    ->match('title', 'sora')
    ->enqueue((new SphinxQL($this->conn))->query('SHOW META')) // this returns the object with SHOW META query
    ->enqueue() // this returns a new object
    ->select()
    ->from('rt')
    ->match('content', 'nymph')
    ->executeBatch();

$result 将包含 MultiResultSet 对象。连续调用 $result->getNext() 方法允许您获取包含下一个排队查询结果的 ResultSet 对象。

查询结果

ResultSet

包含查询执行的结果。

  • $result->fetchAllAssoc()

    以关联数组的形式获取所有结果行。

  • $result->fetchAllNum()

    以数字数组的形式获取所有结果行。

  • $result->fetchAssoc()

    以关联数组的形式获取结果行。

  • $result->fetchNum()

    以数字数组的形式获取结果行。

  • $result->getAffectedRows()

    在 DML 查询的情况下,返回受影响行数。

MultiResultSet

包含多查询执行的结果。

  • $result->getNext()

    返回包含下一个查询结果的 ResultSet 对象。

辅助工具

Helper 类包含不需要“查询构建”的有用方法。

请记住使用 ->execute() 来获取结果。

  • Helper::pairsToAssoc($result)

    从 SHOW 命令获取配对并将其返回为键=值关联数组。

以下方法返回准备好的 SphinxQL 对象。您也可以使用 ->enqueue($next_object)

<?php
use Foolz\SphinxQL\SphinxQL;

$result = (new SphinxQL($this->conn))
    ->select()
    ->from('rt')
    ->where('gid', 9003)
    ->enqueue((new Helper($this->conn))->showMeta()) // this returns the object with SHOW META query prepared
    ->enqueue() // this returns a new object
    ->select()
    ->from('rt')
    ->where('gid', 201)
    ->executeBatch();
  • (new Helper($conn))->showMeta() => 'SHOW META'
  • (new Helper($conn))->showWarnings() => 'SHOW WARNINGS'
  • (new Helper($conn))->showStatus() => 'SHOW STATUS'
  • (new Helper($conn))->showTables() => 'SHOW TABLES'
  • (new Helper($conn))->showVariables() => 'SHOW VARIABLES'
  • (new Helper($conn))->setVariable($name, $value, $global = false)
  • (new Helper($conn))->callSnippets($data, $index, $query, $options = array())
  • (new Helper($conn))->callKeywords($text, $index, $hits = null)
  • (new Helper($conn))->describe($index)
  • (new Helper($conn))->createFunction($udf_name, $returns, $soname)
  • (new Helper($conn))->dropFunction($udf_name)
  • (new Helper($conn))->attachIndex($disk_index, $rt_index)
  • (new Helper($conn))->flushRtIndex($index)
  • (new Helper($conn))->optimizeIndex($index)
  • (new Helper($conn))->showIndexStatus($index)
  • (new Helper($conn))->flushRamchunk($index)

Percolate

《Percolate》类提供了Manticore Search中“Percolate查询”功能的方法。有关percolate查询的更多信息,请参阅Percolate查询文档。

INSERT

Percolate类为在percolate索引中插入查询提供了一个专门的助手。

<?php
use Foolz\SphinxQL\Percolate;

$query = (new Percolate($conn))
     ->insert('full text query terms',false)      
     ->into('pq')                                              
     ->tags(['tag1','tag2'])                                  
     ->filter('price>3')                                      
     ->execute();
  • $pq = (new Percolate($conn))->insert($query,$noEscape)

    开始一个INSERT。每个插入只允许添加一个查询。默认情况下,查询字符串将被转义。可选的第二个参数$noEscape可以设置为true以不应用转义。

  • $pq->into($index)

    设置插入的percolate索引。

  • $pq->tags($tags)

    为每个查询设置一个标签列表。接受字符串数组或以逗号分隔的字符串。

  • $pq->filter($filter)设置属性过滤字符串。该字符串必须与WHERE属性过滤子句中的字符串相同

  • $pq->execute()

    执行INSERT

CALLPQ

搜索为输入文档提供匹配的存储查询。

<?php
use Foolz\SphinxQL\Percolate;
$query = (new Percolate($conn))
     ->callPQ()
     ->from('pq')                                              
     ->documents(['multiple documents', 'go this way'])        
     ->options([                                               
           Percolate::OPTION_VERBOSE => 1,
           Percolate::OPTION_DOCS_JSON => 1
     ])
     ->execute();
  • $pq = (new Percolate($conn))->callPQ()

    开始一个CALL PQ

  • $pq->from($index)

    设置percolate索引。

  • $pq->documents($docs)

    设置传入的文档。$docs可以是

    • 单个纯文本字符串(需要将Percolate::OPTION_DOCS_JSON设置为0)
    • 纯文本字符串数组(需要将Percolate::OPTION_DOCS_JSON设置为0)
    • 单个JSON文档
    • JSON文档数组
    • 包含JSON对象数组的JSON对象
  • $pq->options($options)

    设置CALL PQ的选项。有关CALL PQ参数的更多信息,请参阅Manticore文档。

    • Percolate::OPTION_DOCS_JSON作为docs_json)默认为1(文档是JSON对象)。需要将其设置为0以使用纯文本字符串文档。当将查询发送到Manticore时,作为关联数组添加的文档将转换为JSON。
    • Percolate::OPTION_VERBOSE作为verbose)在后续的SHOW META中打印更多信息,默认为0
    • Percolate::OPTION_QUERY作为query)返回所有存储查询字段,默认为0
    • Percolate::OPTION_DOCS作为docs)按文档匹配提供结果集(而不是按查询),默认为0
  • $pq->execute()

    执行CALL PQ

Laravel

Laravel的依赖注入和实时外观使得SphinxQL查询构建器的使用更加方便。

// Register connection:
use Foolz\SphinxQL\Drivers\ConnectionInterface;
use Foolz\SphinxQL\Drivers\Mysqli\Connection;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton(ConnectionInterface::class, function ($app) {
            $conn = new Connection();
            $conn->setParams(['host' => 'domain.tld', 'port' => 9306]);
            return $conn;
        });
    }
}

// In another file:
use Facades\Foolz\SphinxQL\SphinxQL;

$result = SphinxQL::select('column_one', 'colume_two')
    ->from('index_ancient', 'index_main', 'index_delta')
    ->match('comment', 'my opinion is superior to yours')
    ->where('banned', '=', 1)
    ->execute();

外观也可以与HelperPercolate一起使用。