foolz/sphinxql-query-builder

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

3.0.2 2022-02-26 00:40 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 扩展、PDOSphinx/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的数组,该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块中,因为字符顺序可能会throw查询错误。

    <?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()

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

多查询

  • $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