ripaclub/sphinxsearch

Sphinx Search 库提供了 SphinxQL 索引和搜索功能

0.8.1 2016-03-26 03:10 UTC

This package is not auto-updated.

Last update: 2024-09-14 13:28:31 UTC


README

Latest Stable Version Build Status Coveralls branch Total Downloads

Sphinx Search 库提供了 SphinxQL 索引和搜索功能。

简介

本库旨在提供

  • 基于 Zend\Db\SqlSphinxQL 查询构建器
  • 一个简单的 搜索
  • 用于处理 RT 索引的 索引器
  • 通过 Zend\Db\Adapter 的 SphinxQL 连接工厂

我们还准备了一套相关的 实用工具。您可以使用它们与此库配合使用。

注意

由于通过 Sphinx API 可用的所有内容也通过 SphinxQL 可用,但反之则不然(即,写入 RT 索引只能通过 SphinxQL 进行),因此本库不使用 SphinxClient PHP 扩展。

安装

使用 composer

将以下内容添加到您的 composer.json 文件中

"require": {
	"ripaclub/sphinxsearch": "~0.8.0",
}
注意

从版本 0.8.1 开始,完全支持 PHP 7 和 Zend Framework 3.x 系列的组件。

0.8.x 系列开始,最低要求是 PHP >= 5.5 和 Zend Framework 依赖项 >= 2.4。

如果您必须使用小于(或等于)5.4 的 PHP 版本和/或小于(或等于)2.3 的 Zend Framework 依赖项,则可以使用 0.7.1 版本。

配置(简单)

要使用库组件,您需要一个适配器实例。您可以使用内置工厂简单地获取配置适配器,如下面的示例所示

use Zend\ServiceManager\ServiceManager;
use Zend\ServiceManager\Config;

$serviceManagerConfig = new Config([
    'factories' => [
        'SphinxSearch\Db\Adapter\Adapter' => 'SphinxSearch\Db\Adapter\AdapterServiceFactory'
    ],
    'aliases' => [
        'sphinxql' => 'SphinxSearch\Db\Adapter\Adapter'
    ]
]);
$serviceManager = new ServiceManager();
$serviceManagerConfig->configureServiceManager($serviceManager);
$serviceManager->setService('Config', [
    'sphinxql' => [
        'driver'    => 'pdo_mysql',
        'hostname'  => '127.0.0.1',
        'port'      => 9306,
        'charset'   => 'UTF8'
    ]
]);

$adapter = $serviceManager->get('sphinxql');
注意

仅支持两种驱动程序

  • pdo_mysql
  • mysqli

有关更多详细信息,请参阅 适配器服务工厂 部分。

用法

搜索

假设 $adapter 已通过 ServiceManager 获取

use SphinxSearch\Search;
use SphinxSearch\Db\Sql\Predicate\Match;

$search = new Search($adapter);
$rowset = $search->search('foo', new Match('?', 'ipsum dolor'));

echo 'Founds row:' . PHP_EOL;
foreach ($rowset as $row) {
	echo $row['id'] . PHP_EOL;
}

search() 方法将索引名称(或索引数组)作为第一个参数,将 where 条件(与 Zend\Db\Sql\Select::where() 相同)作为第二个参数。此外,search() 的第二个参数可以接受一个闭包,该闭包将传递给正在构建的 SELECT 查询的当前 Select 对象。

以下用法是可能的

use SphinxSearch\Search;
use SphinxSearch\Db\Sql\Select;
use SphinxSearch\Db\Sql\Predicate\Match;

$search = new Search($adapter);
$rowset = $search->search('foo', function(Select $select) {
	$select->where(new Match('?', 'ipsum dolor'))
	       ->where(['c1 > ?' => 5])
               ->limit(1);
});

SphinxSearch\Db\Sql\Select 类(类似于我们扩展的 Zend\Db\Sql\Select)支持以下与 SQL 标准子句相关的功能

$select->from($table)
$select->columns(array $columns)
$select->where($predicate, $combination = Predicate\PredicateSet::OP_AND)
$select->group($group)
$select->having($predicate, $combination = Predicate\PredicateSet::OP_AND)
$select->order($order)
$select->limit($limit)
$select->offset($offset)
// And also variable overloading for:
$select->where
$select->having

因此,它添加了一些 SphinxQL 特定的方法

$select->withinGroupOrder($withinGroupOrder)
$select->option(array $values, $flag = self::OPTIONS_MERGE)

其他实用方法如 setSpecificationsgetRawStatereset 均完全支持。

相反,quantifierjoincombine 只是忽略,因为 SphinxQL 语法中没有它们。

索引器

假设 $adapter 已经通过 ServiceManager 获取,我们可以在索引上执行文档索引操作,前提是我们操作的是 实时 索引。

use SphinxSearch\Indexer;

$indexer = new Indexer($adapter);
$indexer->insert(
	'foo',
	[
		'id' => 1,
		'short' => 'Lorem ipsum dolor sit amet',
		'text' => 'Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit ...'
	],
	true
);

注意,insert 方法的第三个参数是一个布尔标志,指示是否执行 "upsert" 而不是插入操作。

此外,Indexer 实例允许从实时索引中更新和删除行(分别使用 updatedelete 方法)。

高级

适配器服务工厂

这个库包含两个工厂,以便正确配置 Zend\Db\Adapter\Adapter 以与 Sphinx Search 一起工作。

使用 SphinxSearch\Db\Adapter\AdapterServiceFactory(见上面的 配置 部分),对于单个连接;如果需要使用多个连接,请使用提供的 SphinxSearch\Db\Adapter\AdapterAbstractServiceFactory,并在 ServiceManager 中注册,如下所示

'service_manager' => [
	'abstract_factories' => [
  		'SphinxSearch\Db\Adapter\AdapterAbstractServiceFactory'
	],
]

有关抽象工厂配置,请参阅 Zend Db Adpater Abstract Factory 文档

预处理语句

SphinxQL 不支持预处理语句,但 PDO 驱动器能够模拟客户端预处理语句。为了达到预处理查询的好处,这个库完全支持这个功能。

注意

PDO 驱动器支持预处理和非预处理查询。Mysqli 驱动器不支持预处理查询。

对于 SphinxSearch\SearchSphinxSearch\Indexer,您可以通过 setQueryMode() 使用以下标志之一来选择工作模式

const QUERY_MODE_PREPARED   = 'prepared'; // use prepared statement
const QUERY_MODE_EXECUTE    = 'execute';  // do not use prepared statement
const QUERY_MODE_AUTO       = 'auto';     // auto detect best available option (prepared mode preferred)

使用 auto 选项时,组件将使用可用的最佳执行模式,如果驱动器支持,则优先选择预处理模式。

处理类型

这个库旨在在支持的驱动器和模式下标准化 API 使用,但由于 SphinxQL 的限制,有一些考虑事项

  • NULL

    SphinxQL 不支持 NULL。该库透明地处理它以与 SQL 兼容:如果您尝试使用值为 NULL 的值,驱动器将抛出异常。

  • boolean

    SphinxQL 没有原生布尔类型,但如果您尝试使用 PHP bool,库和驱动器将分别将值转换为 01

  • integer

    当 SphinxQL 预期 uint 时,PHP 原生整数可以正常工作。请注意,包含整数的字符串在过滤器中不起作用(即 WHERE 子句)。
    警告:PHP 整数是带符号的,而 SphinxQL 仅支持无符号整数和 UNIX 时间戳。

  • float

    由于与 float 值相关的 SphinxQL 特定问题(尤其是在 WHERE 子句中),默认情况下,它们被转换为与 32 位单精度兼容的字符串表示形式,然后作为文本包括在 SQL 查询中,即使在使用预处理语句的情况下也是如此。

    此功能仅适用于值为原生 PHP float 的情况(无论如何,包含浮点数的字符串在 Sphinx 中不起作用)。如果需要,可以使用 $adapter->getPlatform()->enableFloatConversion(false) 全局禁用此行为。

    警告:禁用浮点转换功能可能会产生意外的行为,一些值得注意的示例

    • 实际上,Sphinx SQL 解释器将不带小数部分的数字视为整数。因此,假设 f1 为浮点列,如果您尝试 WHERE f1 = 10,您将得到 42000 - 1064 - index foo: 不支持在浮点列上的 'intvalues' 过滤类型,否则如果您尝试 WHERE f1 = 10.0,它将正常工作。
    • 由于 SphinxQL 不支持将浮点数作为字符串引用,并且 PDO 驱动在预处理语句模式下没有绑定双精度(SQL 浮点)参数的方法,PDO 驱动将只将其转换为字符串,并产生一个本地化的转换(与 PHP 的 echo 相同),因此只有在 LC_NUMERIC 设置符合小数点作为十进制分隔符时(例如,您可以使用 LC_NUMERIC='C')才会工作。

因此,我们建议在构建查询时始终使用合适的 PHP 原生类型(即,不要使用字符串表示数值字段)。

有用链接:[Sphinx 属性文档](http://sphinxsearch.com/docs/current.html#attributes)。

SQL 对象

正如 Zend\Db\Sql,这个库提供了一系列 SQL 对象。

  • SphinxSearch\Db\Sql\Select搜索 段落中解释。
  • SphinxSearch\Db\Sql\Insert
  • SphinxSearch\Db\Sql\Replace 与插入相同,但会覆盖重复的 ID
  • SphinxSearch\Db\Sql\Update 具有处理 OPTION 子句的能力
  • SphinxSearch\Db\Sql\Delete
  • SphinxSearch\Db\Sql\Show

每个都可以通过 SphinxSearch\Db\Sql\Sql 类的方法检索

use SphinxSearch\Db\Sql\Sql;

$sql = new Sql($adapter);
$select = $sql->select();  	// @return SphinxSearch\Db\Sql\Select
$insert = $sql->insert();   // @return SphinxSearch\Db\Sql\Insert
$insert = $sql->replace();	// @return SphinxSearch\Db\Sql\Replace
$update = $sql->update(); 	// @return SphinxSearch\Db\Sql\Update
$delete = $sql->delete();  	// @return SphinxSearch\Db\Sql\Delete
$show   = $sql->show(); 	// @return SphinxSearch\Db\Sql\Show

或者可以像以下示例中那样直接实例化

use SphinxSearch\Db\Sql\Update;
use SphinxSearch\Db\Sql\Predicate\Match;

$update = new Update;
$update->from('myindex')
       ->set(['bigattr' => 1000, 'fattr' => 3465.23])
       ->where(new Match('?', 'hehe'))
       ->where(['enabled' => 1])
       ->option('strict', 1);

然后您可以通过以下方式执行查询

$statement = $sql->prepareStatementForSqlObject($select);
$results = $statement->execute();

或者使用 SearchIndexer 组件

$resultset = $indexer->updateWith($update);

因此,每个对象(具有 where() 方法)都支持 Match 表达式,如下一段所述。

查询表达式

SphinxSearch\Query\QueryExpression 类提供了一种占位符表达式方式和字符串转义机制,以便安全地使用 Sphinx 查询语法。此外,组件设计允许它独立使用,因为它不依赖于其他库组件。

一些示例

use SphinxSearch\Query\QueryExpression;

$query = new QueryExpression('@title ? @body ?', ['hello', 'world']);
echo $query->toString(); //outputs: @title hello @body world


echo $query->setExpression('"?"/3')
           ->setParameters(['the world is a wonderful place, but sometimes people uses spe(ia| ch@rs'])
           ->toString(); //outputs: "the world is a wonderful place, but sometimes people uses spe\(ia\| ch\@rs"/3

echo $query->setExpression('? NEAR/? ? NEAR/? "?"')
           ->setParameters(['hello', 3, 'world', 4, '"my test"'])
           ->toString(); //outputs: hello NEAR/3 world NEAR/4 "my test"

SphinxSearch\Db\Sql\Predicate\Match 类内部使用 QueryExpression,因此您可以直接在 SQL 查询中使用它。

use SphinxSearch\Adapter\Platform\SphinxQL;
use SphinxSearch\Db\Sql\Select;
use SphinxSearch\Db\Sql\Predicate\Match;

$select = new Select;
$select->from('myindex')
       ->where(new Match('? NEAR/? ? NEAR/? "?"', ['hello', 3, 'world', 4, '"my test"']))
       ->where(['enabled' => 1]);

//outputs: SELECT * from `foo` WHERE MATCH('hello NEAR/3 world NEAR/4 "my test"') AND `enabled` = 1
echo $select->getSqlString(new SphinxQL());

测试

库源代码(在 master 分支 上)100% 通过单元测试覆盖。

一旦通过 composer 安装了开发依赖项,您就可以运行 phpunit

./vendor/bin/phpunit --exclude-group=integration

要运行集成测试,请执行

./vendor/bin/phpunit
注意

要执行集成测试,您需要一个运行中的 SphinxSearch 实例(例如,使用正确配置的 docker 映像)。

Analytics