joacub / sphinxsearch
Sphinx Search 库提供 SphinxQL 索引和搜索功能
Requires
- php: >=5.3.3
- zendframework/zend-db: ~2.2
- zendframework/zend-servicemanager: ~2.2
- zendframework/zend-stdlib: ~2.2
Requires (Dev)
- pdepend/pdepend: 2.0.*
- phpmd/phpmd: 2.0.*
- phpunit/phpunit: 4.2.*
- squizlabs/php_codesniffer: 1.5.*
Suggests
- ripaclub/zf2-sphinxsearch: ZF2 integration module for SphinxSearch library
- ripaclub/zf2-sphinxsearch-tool: ZF2 module/tool that provides a set of tools to configure and handle SphinxSearch engine
This package is not auto-updated.
Last update: 2024-09-22 06:22:11 UTC
README
Sphinx Search 库提供 SphinxQL 索引和搜索功能。
简介
本库旨在提供
- 基于 Zend\Db\Sql 的 SphinxQL 查询构建器
- 一个简单的
Search
类 - 一个用于处理 RT 索引的
Indexer
类 - 通过 Zend\Db\Adapter 的 SphinxQL 连接工厂
注意
本库不使用 SphinxClient
PHP 扩展,因为通过 Sphinx API 可用的所有功能也都可通过 SphinxQL 使用,反之则不然(例如,写入 RT 索引只能通过 SphinxQL 进行)。
安装
使用 composer
将以下内容添加到您的 composer.json
文件中
"require": { "php": ">=5.3.3", "ripaclub/sphinxsearch": "~0.6", }
或者使用 git 子模块
git submodule add https://github.com/ripaclub/sphinxsearch.git ripaclub/sphinxsearch
配置(简单)
通过 service_manager
配置节点注册提供的工厂
'service_manager' => array( 'factories' => array( 'SphinxSearch\Db\Adapter\Adapter' => 'SphinxSearch\Db\Adapter\AdapterServiceFactory', ), // Optionally 'aliases' => array( 'sphinxql' => 'SphinxSearch\Db\Adapter\Adapter' ), )
然后在您的配置中添加 sphinxql
节点,并使用示例中的连接参数进行配置
'sphinxql' => array( 'driver' => 'pdo_mysql', 'hostname' => '127.0.0.1', 'port' => 9306, 'charset' => 'UTF8' )
更多详细信息请参阅“适配器服务工厂”部分。
用法
搜索
假设 $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(array('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)
其他实用方法,如 setSpecifications
、getRawState
和 reset
,都得到了完全支持。
相反,quantifier
、join
和 combine
只被忽略,因为 SphinxQL 语法中没有这些。
索引器
假设 $adapter
已通过 ServiceManager
获取,我们可以执行文档的索引,前提是我们所作用的索引是 实时。
use SphinxSearch\Indexer; $indexer = new Indexer($adapter); $indexer->insert( 'foo', array( '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
实例允许通过 update
和 delete
方法更新和删除实时索引中的行(分别使用方法和方法)。
高级
适配器服务工厂
本库包含两个工厂,以便正确配置 Zend\Db\Adapter\Adapter
以与 Sphinx Search 一起工作。
使用 SphinxSearch\Db\Adapter\AdapterServiceFactory
(参见上文中的配置部分),如果需要使用单个连接;如果需要使用多个连接,则使用随附的SphinxSearch\Db\Adapter\AdapterAbstractServiceFactory
,如下注册到ServiceManager
中:
'service_manager' => array( 'abstract_factories' => array( 'SphinxSearch\Db\Adapter\AdapterAbstractServiceFactory' ), )
有关抽象工厂配置,请参阅Zend Db Adapter Abstract Factory文档。
仅支持两个驱动程序:
PDO_MySQL
Mysqli
预处理语句
SphinxQL不支持预处理语句,但PDO驱动程序可以在客户端模拟预处理语句。为了实现预处理查询的优势,此库完全支持此功能。
注意
PDO驱动程序支持预处理和非预处理查询。Mysqli驱动程序不支持预处理查询。
对于SphinxSearch\Search
和SphinxSearch\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
,则驱动程序将抛出异常。 -
布尔值
SphinxQL没有原生的布尔类型,但如果尝试使用PHP的
bool
,库和驱动程序将分别将值转换为0
或1
。 -
整数
当SphinxQL期望
uint
时,PHP的本地整数可以正常工作。请注意,包含整数的字符串在过滤器中不起作用(即WHERE
子句)。
警告:PHP整数是带符号的,而SphinxQL仅支持无符号整数和UNIX时间戳。 -
浮点数
由于与
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'
)
- 实际上,Sphinx SQL解释器将没有小数部分的数字视为整数。因此,假设
因此,我们建议在构建查询时始终使用合适的PHP本地类型(即,不要使用字符串作为数字字段)。
有用的链接:Sphinx属性文档。
SQL 对象
与Zend\Db\Sql一样,此库提供了一组SQL对象:
SphinxSearch\Db\Sql\Select
在搜索段落中解释SphinxSearch\Db\Sql\Insert
SphinxSearch\Db\Sql\Replace
与插入相同,但会覆盖重复的IDSphinxSearch\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(array('bigattr' => 1000, 'fattr' => 3465.23)) ->where(new Match('?', 'hehe')) ->where(array('enabled' => 1)) ->option('strict', 1);
然后您可以通过以下方式执行查询
$statement = $sql->prepareStatementForSqlObject($select); $results = $statement->execute();
或者使用 Search
或 Indexer
组件
$resultset = $indexer->updateWith($update);
因此,每个对象(具有 where()
)都支持 Match
表达式,如下一节所述。
查询表达式
SphinxSearch\Query\QueryExpression
类提供了一种占位符表达式方式和字符串转义机制,以便安全地使用 Sphinx 查询语法。此外,组件设计允许它独立使用,因为它不依赖于其他库的组件。
一些示例
use SphinxSearch\Query\QueryExpression; $query = new QueryExpression('@title ? @body ?', array('hello', 'world')); echo $query->toString(); //outputs: @title hello @body world echo $query->setExpression('"?"/3') ->setParameters(array('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(array('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/? "?"', array('hello', 3, 'world', 4, '"my test"'))) ->where(array('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 -c tests/
代码质量
运行 phpmd。
./vendor/bin/phpmd library/ text phpmd.xml.dist
运行 phpcs。
./vendor/bin/phpcs --standard=PSR2 library/
运行 pdepend。
./vendor/bin/pdepend --exclude=tests,vendor --summary-xml=pdepend.log library/