cyber-duck / silverstripe-searchly
SilverStripe的Elastic Search集成
Requires
- php: >=7.0.0
- guzzlehttp/guzzle: ~6 || ~7
- silverstripe/framework: ^4
This package is auto-updated.
Last update: 2024-09-08 13:34:04 UTC
README
此软件包可以为运行在本地环境、服务器(如AWS)或Elastic Search服务(如Searchly)上的任何Elastic Search实例添加索引DataObjects的能力。
适用于SilverStripe 4.*
安装
将以下内容添加到您的composer.json文件中,并运行/dev/build?flush=all
{ "require": { "cyber-duck/silverstripe-searchly": "4.1.*" } }
配置
有关配置选项,请参阅_config/searchly.yml
。
设置您的Elastic Search端点
在.env文件中添加SEARCHLY_BASE_URI变量,并使用任何有效的ES端点(AWS、searchly等)
SEARCHLY_BASE_URI="https://site:{api-key}@xyz.searchly.com" -
或者对于本地docker ES实例或类似实例
SEARCHLY_BASE_URI="http://es:9200"
设置可索引的DataObject字段和关系
模型及其关系可以作为一个可搜索的对象一起索引。要索引字段及其关系,您可以在DataObject上使用searchable_*配置数组。
以下示例中,Tags和ContentBlocks关系需要它们自己的searchable_*配置。在索引时,这些关系将被遍历并创建嵌套对象。
private static $searchable_db = [ 'Title', 'Content' ]; private static $searchable_has_many = [ 'Tags' ]; private static $searchable_many_many = [ 'ContentBlocks' ];
对搜索索引执行操作
创建一个搜索索引实例,您可以访问更改和操作搜索索引的功能,如创建新的索引、添加/删除记录等。
$index = new SearchIndex( 'pages', // the index name, can be hard coded or better to pull from a .env var 'pages', // the searchly index _type [Page::class] // an array of models to index, can be pages or non pages );
createIndex($mappings = [], $settings = [])
在您的搜索索引实例上调用此方法将构建ES端点索引。有关映射和设置的完整配置,请参阅Elastic Search文档。
$mappings = [ 'Created' => [ 'type' => 'date', ], 'LastEdited' => [ 'type' => 'date', ], 'ClassName' => [ 'type' => 'keyword', ], 'Title' => [ 'type' => 'text', 'boost' => 100, ], 'Link' => [ 'type' => 'text', 'index' => false, ] ]; $settings = [ 'analysis' => [ 'analyzer' => [ 'default' => [ 'type' => 'english', ] ] ] ]; $index->createIndex($mappings, $settings);
deleteIndex()
此方法将完全从您的ES端点删除搜索索引。
$index->deleteIndex();
resetIndex($mappings = [], $settings = [])
此方法将调用deleteIndex()然后调用createIndex()。请确保传递与createIndex()相同的映射和设置配置;
$index->resetIndex($mappings, $settings);
index(array $filters = [])
此方法将推送所有模型到您在创建搜索索引实例时指定的ES端点索引。
以下示例中,调用index将遍历所有页面和文件模型,创建它们的JSON表示,并将它们推送到ES端点索引。
$index = new SearchIndex( 'models', // the index name, can be hard coded or better to pull from a .env var 'models', // the searchly index _type [ Page::class, File::class ] ); $index->index();
如果您希望从索引中排除某些模型,还可以应用过滤器。
$index->index([ Page::class => [ 'ClassName:not' => ErrorPage::class, ], File::class => [ 'ClassName:not' => Folder::class, ], ]);
您还可以通过调用index然后getRecords()来查看发送到ES端点索引的所有数据。这将返回一个JSON对象数组。
$index->index([...])->getRecords();
indexRecord(DataObject $record)
将单个数据对象添加到ES端点索引
$index->indexRecord( Page::get()->find('ID', 1) );
removeRecord(DataObject $record)
从ES端点索引中删除单个数据对象
$index->removeRecord( Page::get()->find('ID', 1) );
创建一个索引任务
创建索引的最简单方法是创建一个SilverStripe任务并运行它以创建/重建所有索引
use CyberDuck\Searchly\Index\SearchIndex; use SilverStripe\Assets\File; use SilverStripe\Dev\BuildTask; class SearchIndexTask extends BuildTask { protected $enabled = true; protected $title = "Searchly Pages index task"; protected $description = "Indexes all site pages for use in searchly"; public function run($request) { $mappings = [ ... // your configuration ]; $settings = [ ... // your configuration ]; $index = new SearchIndex( 'pages', // the index name, can be hard coded or better to pull from a .env var 'pages', // the searchly index _type [Page::class] // an array of models to index, can be pages or non pages ); $index->resetIndex($mappings, $settings); $index->index(); $index = new SearchIndex( 'files', // the index name, can be hard coded or better to pull from a .env var 'files', // the searchly index _type [File::class] // an array of models to index, can be pages or non pages ); $index->resetIndex($mappings, $settings); $index->index(); } }
如果您在索引大量模型时遇到PHP超时,可以尝试增加执行时间
public function run($request) { ini_set('max_execution_time', 300); $index = new SearchIndex(...
执行搜索
要执行搜索查询,请创建一个新的SearchQuery实例,并将搜索词和索引名称注入到构造函数中。
use CyberDuck\Searchly\Index\SearchQuery; $query = new SearchQuery( $term, // the search term 'pages' // the index name, can be hard coded or better to pull from a .env var );
配置您的搜索查询
您可以控制返回的结果数量。对于非常大的数据集非常有用。
$query->setSize(50);
您还可以控制AND / OR匹配
$query->setOperator('OR');
还有一个自定义方法可以设置analyze_wildcard配置为true / false
$query->setWildcard(true);
或者,您可以为任何情况构建自己的高度复杂的配置。
$query->setConfig('sort', [['Created' => 'desc']]); $query->setConfig('query', [ 'bool' => [ 'must' => [ [ 'query_string' => [ 'query' => '*'.$escapedterm.'*', 'analyze_wildcard' => true, 'default_operator' => 'OR', ] ] ] ] ]);
获取搜索结果
要返回匹配的模型ID数组,可以调用getIDs()方法。
$ids = $query->getIDs();
要返回匹配的对象数组,可以调用getHits()方法。
$objects = $query->getHits();
通过在SearchQuery实例上调用setHighlight()并在调用getHighlights(),也可以返回高亮/匹配的文本。
$query->setHighlight(true); $highlights = $query->getHighlights();
要返回完整的ES端点响应对象,可以在查询对象上调用getResponse()方法。这对于调试很有用。
$response = $query->getResponse();