openregion/sphinxql-query-builder

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

4.0.0 2023-10-04 10:14 UTC

This package is auto-updated.

Last update: 2024-09-05 07:31:41 UTC


README

Latest Stable Version Total Downloads

关于

这是对 FoolCode 的 SphinxQL 查询构建器 的分支。原始版本似乎不再维护。

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

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

缺少方法?

SphinxQL 发展非常快。

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

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

代码质量

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

唯一没有完全测试的方法是辅助方法,这些方法主要是 SQL 字符串的简单简写。

如何贡献

拉取请求

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

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

风格指南

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

单元测试

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

了解 PHPUnit

安装

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

用法

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

<?php
use OpenRegion\SphinxQL\SphinxQL;
use OpenRegion\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();

驱动程序

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

  • OpenRegion\SphinxQL\Drivers\Mysqli\Connection
  • OpenRegion\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 对象。

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

SphinxQL

  • new SphinxQL($conn)

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

绕过查询转义

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

  • SphinxQL::expr($string)

    返回未转义的字符串。

查询转义

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

  • $conn->escape($value)

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

  • $conn->quoteIdentifier($identifier)

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

  • $conn->quote($value)

    添加引号并转义值。对于数组元素,使用$conn->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 OpenRegion\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 (\OpenRegion\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 OpenRegion\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 OpenRegion\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 类提供了 Manticore Search 中 "Percolate 查询" 功能的方法。有关 percolate 查询的更多信息,请参阅 Percolate 查询 文档。

INSERT

Percolate 类提供了一个用于在 percolate 索引中插入查询的专用辅助工具。

<?php
use OpenRegion\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。每个 insert 允许添加一个查询。默认情况下,查询字符串将被转义。可选的第二个参数 $noEscape 可以设置为 true 以取消转义。

  • $pq->into($index)

    设置插入的 percolate 索引。

  • $pq->tags($tags)

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

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

  • $pq->execute()

    执行 INSERT

CALLPQ

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

<?php
use OpenRegion\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 OpenRegion\SphinxQL\Drivers\ConnectionInterface;
use OpenRegion\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\OpenRegion\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