tomwalder / php-appengine-search
Google App Engine 搜索库 for PHP
Requires
- php: >=5.5.0
Requires (Dev)
- google/appengine-php-sdk: dev-master
- phpunit/phpunit: ~4.0
- satooshi/php-coveralls: dev-master
This package is auto-updated.
Last update: 2024-09-06 11:45:53 UTC
README
在 Google App Engine 上为 PHP 实现全文搜索
这个库提供了原生 PHP 访问 Google App Engine 搜索 API 的方式。
在撰写本文时,没有现成的从 PHP 运行时访问 Google App Engine 全文搜索 API 的方法。
通常这意味着开发人员无法使用 Python/Java/Go 代理模块 来访问该服务 - 这增加了复杂性、另一种语言、额外的潜在故障点以及性能影响。
ALPHA 该库处于非常早期的开发阶段。请勿在生产环境中使用。它会发生变化。
目录
示例
我发现示例是决定是否尝试库的好方法,所以这里有一些供您参考。
// Schema describing a book $obj_schema = (new \Search\Schema()) ->addText('title') ->addText('author') ->addAtom('isbn') ->addNumber('price'); // Create and populate a document $obj_book = $obj_schema->createDocument([ 'title' => 'The Merchant of Venice', 'author' => 'William Shakespeare', 'isbn' => '1840224312', 'price' => 11.99 ]); // Write it to the Index $obj_index = new \Search\Index('library'); $obj_index->put($obj_book);
在这个例子中,我使用了创建文档时的替代数组语法 - 但您也可以这样做
$obj_book = $obj_schema->createDocument(); $obj_book->title = 'Romeo and Juliet'; $obj_book->author = 'William Shakespeare'; $obj_book->isbn = '1840224339'; $obj_book->price = 9.99;
现在我们来做一个简单的搜索并显示输出
$obj_index = new \Search\Index('library'); $obj_response = $obj_index->search('romeo'); foreach($obj_response->results as $obj_result) { echo "Title: {$obj_result->doc->title}, ISBN: {$obj_result->doc->isbn} <br />", PHP_EOL; }
演示应用程序
搜索酒吧!
应用程序: http://pub-search.appspot.com/
代码: https://github.com/tomwalder/pub-search
入门
使用 Composer 安装
要使用 Composer 安装,请在您的 composer.json
中使用此 require 行以获取最新功能,dev-master
"tomwalder/php-appengine-search": "v0.0.4-alpha"
或者,如果您正在使用命令行
composer require tomwalder/php-appengine-search
您可能需要 minimum-stability: dev
查询
您可以为 Index::search
提供一个简单的查询字符串
$obj_index->search('romeo');
对于更多控制和选项,您可以提供一个 Query
对象
$obj_query = (new \Search\Query($str_query)) ->fields(['isbn', 'price']) ->limit(10) ->sort('price'); $obj_response = $obj_index->search($obj_query);
查询字符串
一些简单的、有效的查询字符串
price:2.99
romeo
dob:2015-01-01
dob < 2000-01-01
tom AND age:36
有关更多信息,请参阅 Python 参考文档: https://cloud.google.com/appengine/docs/python/search/query_strings
排序
$obj_query->sort('price');
$obj_query->sort('price', Query::ASC);
限制和偏移量
$obj_query->limit(10);
$obj_query->offset(5);
返回字段
$obj_query->fields(['isbn', 'price']);
表达式
该库支持在结果中请求任意表达式。
$obj_query->expression('euros', 'gbp * 1.45']);
这些可以通过结果文档上的 Document::getExpression()
方法访问,如下所示
$obj_doc->getExpression('euros');
通过 ID 获取文档
您可以直接从索引中通过其唯一的 Doc ID 获取单个文档
$obj_index->get('some-document-id-here');
评分
您可以通过调用 Query::score
方法来启用 MatchScorer。
如果您这样做,结果集中的每个文档都将根据搜索词频率由搜索 API 进行评分 - Google。
如果没有它,所有文档的评分将为 0。
$obj_query->score();
并且结果...
foreach($obj_response->results as $obj_result) { echo $obj_result->score, '<br />'; // Score will be a float }
多排序和评分
如果您应用了 score()
和 sort()
,可能会浪费循环次数并花费金钱。只有当您打算按分数排序时,才对文档进行评分。
如果您需要混合按分数和其他字段的排序,可以使用魔法字段名 _score
,如下所示 - 在这里,我们首先按价格排序,然后按分数排序,因此价格相同的记录将按其分数排序。
$obj_query->score()->sort('price')->sort('_score');
辅助查询和工具
距离
一个常见的用例是根据从已知Geopoint的距离搜索具有Geopoint字段的文档,例如:“查找附近的酒吧”。
有一个辅助方法可以为您完成这项工作,并且它还会在响应中返回距离(以米为单位)。
$obj_query->sortByDistance('location', [53.4653381,-2.2483717]);
这将返回结果,最近的首先显示,并且将返回一个表示距离的表达式 - 前缀为 distance_from_
$obj_result->doc->getExpression('distance_from_location');
自动完成
自动完成是搜索解决方案中最受欢迎和最有用的功能之一。
这可以通过Google App Engine搜索API相对容易地实现,只需稍加技巧!
搜索API不支持本地支持“边缘n-gram”分词(这是我们自动完成所需的!)。
因此,您可以使用库来完成此操作 - 当创建文档时,设置一个带有从包含的 Tokenizer::edgeNGram
函数输出的第二个文本字段。
$obj_tkzr = new \Search\Tokenizer(); $obj_schema->createDocument([ 'name' => $str_name, 'name_ngram' => $obj_tkzr->edgeNGram($str_name), ]);
然后您可以像这样轻松运行自动完成查询
$obj_response = $obj_index->search((new \Search\Query('name_ngram:' . $str_query)));
您可以在我的“酒吧搜索”演示应用程序中看到使用此功能的完整演示应用程序。
创建文档
模式与字段类型
根据Python文档,可用的字段类型如下
- 原子 - 不可分割的字符字符串
- 文本 - 可以按单词进行搜索的纯文本字符串
- HTML - 包含HTML标记标签的字符串,只有标记标签外的文本可以搜索
- 数字 - 浮点数
- 日期 - 包含年/月/日和可选时间的日期
- Geopoint - 纬度和经度坐标
日期
我们支持 DateTime
对象或格式为 YYYY-MM-DD
(PHP date('Y-m-d')
)的日期字符串。
$obj_person_schema = (new \Search\Schema()) ->addText('name') ->addDate('dob'); $obj_person = $obj_person_schema->createDocument([ 'name' => 'Marty McFly', 'dob' => new DateTime() ]);
Geopoint - 位置数据
创建一个包含Geopoint字段的条目
$obj_pub_schema = (new \Search\Schema()) ->addText('name') ->addGeopoint('where') ->addNumber('rating'); $obj_pub = $obj_pub_schema->createDocument([ 'name' => 'Kim by the Sea', 'where' => [53.4653381, -2.2483717], 'rating' => 3 ]);
批量插入
如果您有多个文档,批量插入效率更高。一次最多可以插入200个文档。
只需将Document对象的数组传递给 Index::put()
方法即可,如下所示
$obj_index = new \Search\Index('library'); $obj_index->put([$obj_book1, $obj_book2, $obj_book3]);
替代数组语法
除了直接构造一个新的 Search\Document
并设置其成员数据外,还可以使用 Search\Schema::createDocument
工厂方法,如下所示。
$obj_book = $obj_schema->createDocument([ 'title' => 'The Merchant of Venice', 'author' => 'William Shakespeare', 'isbn' => '1840224312', 'price' => 11.99 ]);
命名空间
在构建索引时,您可以设置一个命名空间。这将允许您支持多租户应用程序。
$obj_index = new \Search\Index('library', 'client1');
分类
搜索API支持两种类型的文档分面用于分类,ATOM和NUMBER。
ATOM可能是您最熟悉的一种,结果集将包括每个唯一分面的计数,类似于以下内容
对于衬衫尺寸
- 小号(9)
- 中号(37)
将分面添加到文档中
$obj_doc->atomFacet('size', 'small'); $obj_doc->atomFacet('colour', 'blue');
在结果中获取分面
$obj_query->facets();
删除文档
您可以通过调用 Index::delete()
方法来删除文档。
它支持一个或多个 Document
对象 - 或一个或多个Document ID字符串 - 或对象和ID字符串的混合!
$obj_index = new \Search\Index('library'); $obj_index->delete('some-document-id'); $obj_index->delete([$obj_doc1, $obj_doc2]); $obj_index->delete([$obj_doc3, 'another-document-id']);
本地开发环境
由于它包含用于支持Python、Java和Go App Engine运行时的功能,因此搜索API支持本地。
最佳实践、免费配额、成本
与大多数App Engine服务一样,搜索是免费的... 但有一个限制!
以及一些值得阅读的最佳实践
Google 软件
我必须包含来自Google的2个文件来使此功能正常工作 - 这是搜索API的协议缓冲区实现。您可以在 /libs
文件夹中找到它们。
它们也可以直接从以下仓库获取:https://github.com/GoogleCloudPlatform/appengine-php-sdk
这两个文件版权属于2007年谷歌公司。
一旦它们被纳入实际的PHP运行时中,我将从这里移除它们。
感谢@sjlangley的帮助。
其他App Engine软件
如果您喜欢这个,您可能对我的PHP Google Cloud Datastore库,PHP-GDS感兴趣